標籤:graphics keyword runtime 圖片緩衝 設定 圖片 group cache override
在做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)
圖片手動回收部分代碼:
Java代碼
- 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()方法裡進行捕獲的時候,時機晚了,沒有捕獲到。現在換到在ImageView的onDraw()裡進行捕獲,上面的異常能夠捕獲。
解決方案(繼承ImageView 重寫onDraw()方法,捕獲異常):
在重寫onDraw()方法中,其實什麼都沒有做,只是添加了一個異常捕獲,即可捕捉到上面的錯誤
Java代碼
- 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");
- }
- }
-
- }
Android手動回收bitmap,引發Canvas: trying to use a recycled bitmap處理