在作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()方法里进行捕获的时候,时机晚了,没有捕获到。如今换到在ImageView的onDraw()里进行捕获,上面的异常可以捕获。canvas
解决方法(继承ImageView 重写onDraw()方法,捕获异常):缓存
在重写onDraw()方法中,其实什么都没有作,只是添加了一个异常捕获,便可捕捉到上面的错误ide
- import android.content.Context;
- import android.graphics.Canvas;
- import android.util.AttributeSet;
- import android.widget.ImageView;
-
- 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");
- }
- }
-
- }