Android手動回收Bitma,引起Canvas: trying to use a recycle

Android手動回收bitmap,引起Canvas: trying to use a recycled bitmap處理

在作Android的開發的時候,在ListView 或是 GridView中須要加載大量的圖片,爲了不加載過多的圖片引發OutOfMemory錯誤,設置了一個圖片緩存列表Map<String, SoftReference<Bitmap>> imageCache , 並對其進行維護,在圖片加載到必定數量的時候,就手動回收掉以前加載圖片的bitmap,此時就引發了以下錯誤: java

 

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41de4380
     at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)
     at android.graphics.Canvas.drawBitmap(Canvas.java:1127)
     at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)
     at android.widget.ImageView.onDraw(ImageView.java:961)
     at android.view.View.draw(View.java:13458)
     at android.view.View.draw(View.java:13342)
     at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
     at android.view.View.draw(View.java:13461)
     at android.view.View.draw(View.java:13342)

 

 

圖片手動回收部分代碼: android

 

Bitmap removeBitmap = softReference.get();
if(removeBitmap != null && !removeBitmap.isRecycled()){
	removeBitmap.recycle(); //此句形成的以上異常
	removeBitmap = null;
}

 

網上有好多人說應該把recycle()去掉,我的認爲去掉後會引發內存持續增加,雖然將bitmap設置爲了null,可是系統並無對其進行真正的回收,仍然佔有內存,便是調用了System.gc() 強制回後之後,內存仍然沒有下去,若是依靠內存達到上限時系統本身回收的話,我的以爲太晚了,已經對應用形成了影響,應用應該是比較卡了,因此仍是贊同加上bitmap.recycle() ,可是又會引發 Canvas: trying to use a recycled bitmap 異常,困擾了好久,開始嘗試從其它方面着手來解決這個問題,即然是異常就應該可以捕獲到,可是在Adapter裏的getView()方法裏進行捕獲的時候,時機晚了,沒有捕獲到。如今換到在ImageViewonDraw()裏進行捕獲,上面的異常可以捕獲。 canvas

 

解決方法(繼承ImageView 重寫onDraw()方法,捕獲異常): 緩存

在重寫onDraw()方法中,其實什麼都沒有作,只是添加了一個異常捕獲,便可捕捉到上面的錯誤 ide

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * 重寫ImageView,避免引用已回收的bitmap異常
 * 
 * @author zwn
 * 
 */
public class MyImageView extends ImageView {

	public MyImageView (Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		try {
			super.onDraw(canvas);
		} catch (Exception e) {
			System.out
					.println("MyImageView  -> onDraw() Canvas: trying to use a recycled bitmap");
		}
	}

}
相關文章
相關標籤/搜索