Android中如何避免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()方法中):
在Activity destory 時注意,drawable.setCallback(null); 防止Activity 得不到及時的釋放。Drawable drawable = getResources().getDrawable(R.drawable.id); ImageView imageView = new ImageView(this); imageView.setBackgroundDrawable(drawable);
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。