Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理

今日长缨在手,何时缚住苍龙。这篇文章主要讲述Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理相关的知识,希望能为你提供帮助。
在做android的开发的时候,在ListView 或是 GridView中需要加载大量的图片,为了避免加载过多的图片引起OutOfMemory错误,设置了一个图片缓存列表 Map< String, SoftReference< Bitmap> > imageCache , 并对其进行维护,在图片加载到一定数量的时候,就手动回收掉之前加载图片的bitmap,此时就引起了如下错误:
 
java代码  

Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理

文章图片
  1. java.lang.RuntimeException:  Canvas:  trying  to  use  a  recycled  bitmap  android.graphics.Bitmap@41de4380   
  2.         at  android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)   
  3.         at  android.graphics.Canvas.drawBitmap(Canvas.java:1127)   
  4.         at  android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)   
  5.         at  android.widget.ImageView.onDraw(ImageView.java:961)   
  6.         at  android.view.View.draw(View.java:13458)   
  7.         at  android.view.View.draw(View.java:13342)   
  8.         at  android.view.ViewGroup.drawChild(ViewGroup.java:2929)   
  9.         at  android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)   
  10.         at  android.view.View.draw(View.java:13461)   
  11.         at  android.view.View.draw(View.java:13342)   
 
 
图片手动回收部分代码:
 
Java代码  
Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理

文章图片
  1. Bitmap  removeBitmap  =  softReference.get();    
  2. if(removeBitmap  !=  null  & &   !removeBitmap.isRecycled()){   
  3.         removeBitmap.recycle();   //此句造成的以上异常   
  4.         removeBitmap  =  null;    
  5. }   
 
网上有好多人说应该把recycle()去掉,个人认为去掉后会引起内存持续增长,虽然将bitmap设置为了null,但是系统并没有对其进行真正的回收,仍然占有内存,即是调用了System.gc() 强制回后以后,内存仍然没有下去,如果依靠内存达到上限时系统自己回收的话,个人觉得太晚了,已经对应用造成了影响,应用应该是比较卡了,所以还是赞同加上bitmap.recycle() ,但是又会引起   Canvas: trying to use a recycled bitmap 异常,困扰了很久,开始尝试从其它方面着手来解决这个问题,即然是异常就应该能够捕获到,但是在Adapter里的getView()方法里进行捕获的时候,时机晚了,没有捕获到。现在换到在ImageView的onDraw()里进行捕获,上面的异常能够捕获。
 
解决方法(继承ImageView 重写onDraw()方法,捕获异常):
【Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理】在重写onDraw()方法中,其实什么都没有做,只是添加了一个异常捕获,即可捕捉到上面的错误
Java代码  
Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理

文章图片
  1. import  android.content.Context;    
  2. import  android.graphics.Canvas;    
  3. import  android.util.AttributeSet;    
  4. import  android.widget.ImageView;    
  5.    
  6. /** 
  7.   *  重写ImageView,避免引用已回收的bitmap异常 
  8.   *   
  9.   *  @author  zwn 
  10.   *   
  11.   */   
  12. public  class  MyImageView  extends  ImageView  {   
  13.    
  14.         public  MyImageView  (Context  context,  AttributeSet  attrs)  {   
  15.                 super(context,  attrs);    
  16.         }   
  17.    
  18.         @Override   
  19.         protected  void  onDraw(Canvas  canvas)  {   
  20.                 try  {   
  21.                         super.onDraw(canvas);    
  22.                 }  catch  (Exception  e)  {   
  23.                         System.out   
  24.                                         .println("MyImageView    ->   onDraw()  Canvas:  trying  to  use  a  recycled  bitmap");    
  25.                 }   
  26.         }   
  27.    

    推荐阅读