2010-12-28 11 views
18

私のアプリケーションでは、私の写真のビデオの場合、私はスケーリングを行ったが、私は時々メモリの例外を得る、どのように私はメモリを処理することができます例外的に効率的。androidどのようにメモリの例外を処理する

+0

OutOfMemory「エラー」は「例外」ではありません。 'Error'と' Excpetion'には大きな違いがある –

答えて

28

イメージサイズが使用可能なメモリよりも小さいことを確認してから、ロードしてください。したがって、OutOfMemoryExceptionを処理する最も効率的な方法は、例外を避けるために大量のデータをメモリにロードしようとしないようにアプリケーションをアーキテクチャすることです。

12

OutOfMemoryを処理できません。どう思いますか?

デバイスのメモリがいっぱいですが、例外があります。そして、あなたは魔法のように例外を取り除くために何かをすると、今度はヒープが増えます。それは不可能です、あなたは知っています。

OutOfMemoryは、発生後には処理しないでください。

+20

これはとても激しく聞こえます –

+4

おそらくOutOfMemoryを取得するケースの大半は(この質問のように)ビットマップの読み込みであり、できる。多くの場合、Nメガバイトのイメージを読み込むことはできませんが、N/4メガバイトのイメージを読み込むことはできます。 BitmapFactoryを使用します。inSampleSize> = 1のオプション、および各再試行の前にinSampleSize * = 2を実行します。 –

+19

実際にこの投稿は間違っています。デバイスメモリは必ずしも一杯になっているとは限りませんOutOfMemoryは、要求されたメモリ量を割り当てることができない場合に発生します。使用可能な40MBがあり、45MBを割り当てようとすると、OutOfMemoryが取得されますが、まだ40MBの空き容量があります。 – xtempore

8

デバイスがメモリ不足のときに呼び出されるa method in Activityがありますが、これはキャッシュファイルのクリーニングをトリガするためにのみ使用できます。これは、アプリケーションプロセスがメモリ不足になることを意味するものではありません。

また、try catchブロックを追加してErrorまたはOutOfMemoryErrorをキャッチすることもできますが、これは遅すぎます。

多くのビットマップまたは大きなビットマップを処理することは、アンドロイドアプリケーションでは実際には困難です。あなたはRomain Guyのthis articleでこのテーマに関するいくつかのヒントを見つけるでしょう。

BitmapFactory.decode *()メソッドに提供するBitmapFactory.optionsのサンプルサイズを指定することで、必要な解像度にビットマップを直接ロードすることもできます。

+1

onLowMemoryは、別のアプリケーションがより多くのメモリを必要とするときに呼び出されることに注意してください。アプリケーションのメモリが不足しているときではありません。したがって、OutOfMemoryErrorがスローされたときにonLowMemoryが呼び出されることはありません。 – Robert

2

イメージビューにjpegをロードし、メモリが不足していないかどうかをチェックし、適合するまで再スケーリングするこのルーチンを試し始めました。

static public boolean tryJpegRead(ImageView imageView, File fn){ 
if (!fn.exists()){ 
    Log.d("ANDRO_ASYNC",String.format("missing file %s",fn.getAbsolutePath())); 
    return false; 
} 
BitmapFactory.Options o = new BitmapFactory.Options(); 
    for (int i = 1; i<10; i++){ 
     o.inSampleSize = i; 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(fn.getAbsolutePath(), o); 
     int h = o.outHeight; 
     int w = o.outWidth; 
     Log.d("ANDRO_ASYNC",String.format("going in h=%d w=%d resample = %d",h,w,o.inSampleSize)); 
     o.inJustDecodeBounds = false; 
     try{ 
      imageView.setImageBitmap(
       Bitmap.createScaledBitmap(
         BitmapFactory.decodeFile(fn.getAbsolutePath(), o), 
         w, 
         h, 
         true)); 
      return true; // only happens when there is no error 
     }catch(OutOfMemoryError E){ 
      Log.d("ANDRO_ASYNC",String.format("catch Out Of Memory error")); 
    //  E.printStackTrace(); 
      System.gc(); 
     }   
    } 
    return false; 
} 
+0

アイデアがいいです。待ち時間を追加しますか? – drulabs

2

、操作をビットマップに関連のOutOfMemoryエラーに対処する復号されたビットマップのサイズを確認する最善であると限り私が唯一の選択肢を知っています。コードは次のとおりです。

public static BitmapFactory.Options getBitmapOptionsWithoutDecoding(String url){ 
    BitmapFactory.Options opts = new BitmapFactory.Options(); 
    opts.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(url, opts); 
    return opts; 
} 

public static int getBitmapSizeWithoutDecoding(String url){ 
    BitmapFactory.Options opts = getBitmapOptionsWithoutDecoding(url); 
    return opts.outHeight*opts.outWidth*32/(1024*1024*8); 
} 

//ref:http://stackoverflow.com/questions/6073744/android-how-to-check-how-much-memory-is-remaining 
public static double availableMemoryMB(){ 
    double max = Runtime.getRuntime().maxMemory()/1024; 
    Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo(); 
    Debug.getMemoryInfo(memoryInfo); 
    return (max - memoryInfo.getTotalPss())/1024; 
} 

public static final long SAFETY_MEMORY_BUFFER = 10;//MB 

public static boolean canBitmapFitInMemory(String path){ 
    long size = getBitmapSizeWithoutDecoding(path); 
    Log.d(TAG, "image MB:"+size); 
    return size <= availableMemoryMB() - SAFETY_MEMORY_BUFFER; 
} 

REF:あなたが背景または類似のような大きなイメージを持っている場合はhttp://developer.android.com/training/displaying-bitmaps/load-bitmap.html

2

、メモリ不足を防止するための簡単な方法は、描画可能nodpiに描画可能-xhdpiから画像を移動することで、しかし、注意してください、これは変更なしでビットマップを読み込みます。 良い方法は、あなたの必要性

0
try { 
// All methods here.... 
} catch(OutOfMemoryException e){ 
// Show an AlertDialog with "Memory is full" title 
// If press ok then starts the process again.. 
} 
1

使用アンドロイドに合わせてBitmapFactory.optionsを使用する必要があります。allowBackup = "true" を、アンドロイド:hardwareAcceleratedは= "false" にし、アンドロイド:largeHeap = "true" を解決するために、この

<application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:roundIcon="@mipmap/ic_launcher" 
     android:hardwareAccelerated="false" 
     android:largeHeap="true" 
     android:theme="@style/AppTheme">