2013-06-21 9 views
5

このエラーに関してstackoverflowで多くの質問がありましたが、私のシナリオでは適切な解決策を説明していません。Androidエラー:java.lang.OutOfMemoryError:ビットマップサイズがVMの予算を超えています

私のアンドロイドアプリケーションでは、ユーザーがボタンをクリックしてギャラリーを開き、画像を選択できるようにする必要があります。そして、その特定の選択されたイメージをレイアウト(UI)のImageViewにロードする必要があります。

これは非常にうまくいきます。以下は、これを達成するために使用しているコードです。 >

 Intent intent = new Intent(); 
     intent.setType("image/*"); 
     intent.setAction(Intent.ACTION_GET_CONTENT); 
     startActivityForResult(Intent.createChooser(intent,"Select Picture"), REQUEST_UPLOAD_IMG); 

そしてonActivityResult - - アップロードボタンクリックで

>

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{  
    //super.onActivityResult(requestCode, resultCode, data);   
    if(resultCode == Activity.RESULT_OK) 
    { 
     if(requestCode==REQUEST_UPLOAD_IMG) 
     {    
      Uri selectedImageURI = data.getData(); 
      uploadImgVW.setImageURI(selectedImageURI);    
     } 
     else 
     { 
      Toast.makeText(MainActivity.this, "You can only select an Image.", Toast.LENGTH_LONG).show(); 
     } 
    } 
} 

しかし、ユーザーがより高いサイズ(サイズのよう2メガバイト)で画像を選択した場合、アプリケーション次のエラーで終了します。しかし、通常の(KBレベルの)画像ではかなりうまくいき、この問題のために何ができるのだろうか(このエラー状況を処理するために)。おかげで...

エラー - >

06-20 16:43:58.445: E/AndroidRuntime(2075): FATAL EXCEPTION: main 
06-20 16:43:58.445: E/AndroidRuntime(2075): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
+0

ビットマップがロードされるたびにリサイクルする必要があります if(b itmap!= null){ bitmap.recycle(); –

+0

初めてアプリがクラッシュするそれが問題です。次のコードも追加しました。ボタンクリックでガベージコレクタを実行するだけです。 [System.gc(); Runtime.getRuntime()。gc(); ] – JibW

+1

@JibWガベージコレクションは問題ではありません、gunnarのように画像のサイズを調整する必要があります – tyczj

答えて

7

効率的how to manage the bitmapsを説明する一連の記事があります。あなたのコードを見ると、画像の大きさを知らなくても画像を読み込むことができます。特に、多くの画像を読み込んで処理すると、これらの問題に直面します。

one of those articlesに記載されているアイデアは、すでにスケールダウンされたビットマップを読み込むことです(まず、イメージの読み込み量を確認してから、ダウンスケーリング係数を計算してから、 )。そのためにはまずImageViewの寸法を知る必要がありますので、表示するターゲットファイルのUriがあるので、BitmapFactory.decode(...)を使用する必要があります。ファイルを作成するには、簡単に行う必要があります。

また、あなたのアプリのメモリ消費量もチェックする必要があります。メモリにハングしている他のリソースがあり、それらをクリーンアップする必要があるかもしれません。私は非常に有用なツール - MATを使用しています。これに関する非常に良い記事はbe found hereです。著者Patrick Dubroyは、このトピックについてGoogle IO 2011で非常に興味深いセッションを開催しました。それは非常に有用だった私のためCheck that out、...

1

は、画像のサイズを変更してから

public static Bitmap decodeUri(Context c, Uri uri, final int requiredSize) 
      throws FileNotFoundException { 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o); 

     int width_tmp = o.outWidth 
       , height_tmp = o.outHeight; 
     int scale = 1; 

     while(true) { 
      if(width_tmp/2 < requiredSize || height_tmp/2 < requiredSize) 
       break; 
      width_tmp /= 2; 
      height_tmp /= 2; 
      scale *= 2; 
     } 

     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     return BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o2); 
    } 

を設定するか、あなたは...あなたはこれを試すかもしれない

if(resultCode == RESULT_OK){ 
       Uri selectedImage = data.getData(); 
       InputStream imageStream = null; 
       try { 
        imageStream = getContentResolver().openInputStream(selectedImage); 
       } catch (FileNotFoundException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream); 
       profileImage.setImageBitmap(Bitmap.createScaledBitmap(yourSelectedImage , 120, 120, false)); 
       } 
0

よう

を使用することができます
BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inTempStorage = new byte[16*1024]; 

Bitmap bitmapImage = BitmapFactory.decodeFile(path, options); 
+0

こんにちはRyderz、これと同じエラーが発生します。 – JibW

関連する問題