zoukankan      html  css  js  c++  java
  • Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理

    在做Android的开发的时候,在ListView 或是 GridView中需要加载大量的图片,为了避免加载过多的图片引起OutOfMemory错误,设置了一个图片缓存列表 Map<String, SoftReference<Bitmap>> imageCache , 并对其进行维护,在图片加载到一定数量的时候,就手动回收掉之前加载图片的bitmap,此时就引起了如下错误:

    Java代码  收藏代码
    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代码  收藏代码
    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()方法,捕获异常):

    在重写onDraw()方法中,其实什么都没有做,只是添加了一个异常捕获,即可捕捉到上面的错误

    Java代码  收藏代码
    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.   
  • 相关阅读:
    安装 kubenetes-dashboard
    使用kubeadm在Centos7上部署kubernetes1.21.1
    批量重命名
    is_valid重写。返回数据格式统一
    django-序列化参数为空报错问题
    单文件日志测试
    文本、目录 空间清理问题
    数仓数据
    滑动验证码(无原图片处理)
    鸟哥私房菜基础篇
  • 原文地址:https://www.cnblogs.com/kim-liu/p/8028791.html
Copyright © 2011-2022 走看看