AndroidでOOM異常を回避する方法

2728 ワード

OOMメモリがオーバーフローしています.OOM異常を回避するには、まず、どのような状況でOOM異常が発生するかを知る必要があります.
1、画像が大きすぎてOOMになる
Androidでbitmapを使うとメモリが溢れやすく、例えば次のエラーが表示されます.
Java.lang.OutOfMemoryError : bitmap size exceeds VM budget.
解決方法:
方法1:等比縮小画像
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
//Options          ,        
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 2;
Bitmap bmp = null;
bmp = BitmapFactory.decodeResource(getResources(), mImageIds[position],opts);
//  
bmp.recycle();//
以上のコードはメモリオーバーフローを最適化できますが、ピクチャサイズを変更するだけで、メモリオーバーフローを完全に解決することはできません.
方法2:画像にソフトリファレンスを採用し、タイムリーにrecyle()操作を行う
SoftReference<Bitmap> bitmap = new SoftReference<Bitmap>(pBitmap);
if(bitmap != null){
	if(bitmap.get() != null && !bitmap.get().isRecycled()){
	bitmap.get().recycle();
	bitmap = null;
	}
}
方法3:ロードピクチャフレームワークを用いてピクチャを処理し、ロードピクチャを専門的に処理するImageLoaderピクチャロードフレームワークなどである.
私たちが学んだXUtilsのBitMapUtilsも処理しています.
2、インタフェース切り替えによるOOM
一般的に、開発中は横画面は禁止されています.往復切替であればactivityのライフサイクルが再破棄されて作成されるからです.
時にはこのような問題を発見することができて、縦スクリーンをN回切り替えた後にOOMになりました.
この問題には固定的な解決方法はないが,以下のいくつかの面から分析することができる.
1、ページレイアウトに大きな画像があるかどうか、背景図などを見てみましょう.
xmlの関連する設定を削除し、プログラムで背景図を設定する(onCreate()メソッドに置く):
Drawable drawable = getResources().getDrawable(R.drawable.id);
ImageView imageView = new ImageView(this);
imageView.setBackgroundDrawable(drawable);
Activity destoryではdrawable.setCallback(null); Activityがタイムリーにリリースされないことを防止します.
2、上記の方法と同様に、xmlプロファイルをviewにロードしてコンテナに入れ、thisを直接呼び出す.setContentView(View view);xmlの重複ロードを回避する方法.
3、ページ切り替え時にできるだけコードを繰り返し使用しない
たとえば、データベースの繰り返し呼び出し、特定のオブジェクトの繰り返し使用など......
3、クエリーデータベースがカーソルを閉じていない
プログラムではデータベースを照会する操作が頻繁に行われますが、Cursorを使用した後に閉じないことがよくあります.クエリ結果セットが比較的小さい場合、メモリの消費量が発見されにくく、メモリの問題が発生するのは、通常の時間に大量に操作されている場合に限られます.これにより、今後のテストと問題のトラブルシューティングに困難とリスクが発生します.
4、Adapterを構築する時、キャッシュのconvertViewを使用しない
ListViewを使用する場合は通常Adapterを使用しますが、ConvertViewをできるだけ使用する必要があります.
なぜconvertViewを使うのですか?
convertViewが空の場合、setTag()メソッドを使用して、各Viewに対してコントロールを格納するViewHolderオブジェクトをバインドします.convertViewが空ではなく、作成したviewを再利用する場合、getTag()メソッドを使用してバインドされたViewHolderオブジェクトを取得することで、findViewByIdによるコントロールの階層クエリーを回避し、コントロールに迅速にナビゲートできます.
5.Bitmapオブジェクトが使用されなくなった時にrecycle()を呼び出してメモリを解放する
Bitmapオブジェクトを手動で操作する場合があり、Bitmapオブジェクトがメモリを占有する場合、使用されなくなったときにBitmapを呼び出すことができます.recycle()メソッドは、このオブジェクトのピクセルが消費するメモリを回収しますが、これは必要ではありません.状況によって異なります.
6、その他
Androidアプリケーションで最も一般的なリソースの解放に注意する必要があるのは、Activityのライフサイクルにおいて、onPause()、onStop()、onDestroy()メソッドで適切なリソースの解放が必要な場合です.ブロードキャストを使用してログアウトしなくてもOOMが発生します.