当你的应用由于加载大量图片出现OOM异常时,肯定会上网搜索关于OOM的文章,并导求相应的解决方案,比如压缩图片大小,或手动回收资源什么的。在这里我们不讨论图片压缩或缓冲这些方法,而是讨论一下手动回收BITMAP时可能出现的问题,亦即 Canvas: trying to use a recycled bitmap。

很容易可以预料到,你必然会遇到并使用如下代码:

  1. if(bitmap != null && !bitmap.isRecycled()){
  2. bitmap.recycle(); //此句造成的以上异常
  3. bitmap = null;
  4. }
  5. System.gc();

然后你将其添加到应用中,用着用着应用崩溃了,查一下LogCat日志,即出现了Canvas: trying to use a recycled bitmap类似的错误。

在进一步探讨之前,我们首先要提醒一下:Android本身就有资源回收机制,它的效果并不似他人所说的“不堪入目”,当你的程序运行时出现GC_CONCURRENT_XX时,说明系统正在回收资源。当然,前提是确实存在垃圾(亦即不再会被引用到的资源)。很多时候,你的应用程序出现OOM异常,是因为应用程序可能对大量的BITMAP资源都有引用,ANDROID自然不会去回收你可能会用到的资源,所以这个时候出现OOM是你的应用程序本身有些不完善,不能怪ANDROID。

一般来说,如果代码已经不再需要使用Bitmap对象了,就可以释放了。释放内存以后,就不能再使用该Bitmap对象了,如果再次使用,就会抛出异常。所以一定要保证不再使用的时候释放。比如,如果是在某个Activity中使用Bitmap,就可以在Activity的onStop()或者onDestroy()方法中进行回收。

那什么才是“不再需要使用的Bitmap对象”呢?废话,不就是后面用不到的图片资源呀,但实际使用的时候,你可能还是会遇到这个异常。其实只要注意BITMAP对象的引用后续是否可能会用到即可,即对象引用的特性!

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

如下所示:

public class TextBm{

private Bitmap bm;

public void setBitmap(Bitmap bm) {this.bm = bm;}

public Bitmap getBitmap(){return this.bm;}

}

TestBm test_bm = new TestBm();

test_bm.setBitmap(BitmapFactory.decodeFile(path1));

//其它更多代码

test_bm.setBitmap(BitmapFactory.decodeFile(path2));

当程序对TestBm的某个实例进行第二次赋值时,由于第一个Bitmap没有引用到,所以就成为垃圾,这个时候就可以在第二次赋值前用开头的回收代码进行回收。这个垃圾也会被ANROID系统自动回收,但不要小看这种垃圾,有些代码用定时刷新线程来做这样的赋值,产生很多垃圾,虽然系统能回收掉,但也会消耗很多时间,看看上图中的pause多少ms就知道了,那就是回收占用的时间。

再如下所示:

test_bm.setBitmap(imageCache.get(str1));//从图片缓存列表中取出1

//其它更多代码

test_bm.setBitmap(imageCache.get(str2));//从图片缓存列表中取出2

注意:这里第二次赋值时,第一个是有引用的(或者在更多其它地方使用过的),就是存在imageCache的Map中,如果你也像上面那样回收,就不是回收test_bm中bm成员的Bitmap1,而是将imageCache中的Bitmap1也给回收了,因为两个对象是同一个Bitmap1,这样一旦还有其它地方要使用,就会发生:

Canvas: trying to use a recycled bitmap

Android开发回收bitmap引发Canvas: trying to use a recycled bitmap错误处理的更多相关文章

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

    在做Android的开发的时候,在ListView 或是 GridView中需要加载大量的图片,为了避免加载过多的图片引起OutOfMemory错误,设置了一个图片缓存列表 Map<String ...

  2. Android Bitmap操作问题之Canvas: trying to use a recycled bitmap

    一.Bitmap.recycle 方法被弃用 在Android中,Bitmap的存储分为两部分,一部分是Bitmap的数据,一部分是Bitmap的引用.在Android2.3时代,Bitmap的引用是 ...

  3. Canvas: trying to use a recycled bitmap android.graphics.Bitmap@XXX

    近期在做和图片相关显示的出现了一个问题,整理一下思路.分享出来给大家參考一下: Exception Type:java.lang.RuntimeException java.lang.RuntimeE ...

  4. 《android开发艺术探索》读书笔记(十二)--Bitmap的加载和Cache

    接上篇<android开发艺术探索>读书笔记(十一)--Android的线程和线程池 No1: 目前比较常用的缓存策略是LruCache和DiskLruCache,LruCache常被用作 ...

  5. Android开发艺术探索》读书笔记 (12) 第12章 Bitmap的加载和Cache

    第12章 Bitmap的加载和Cache 12.1 Bitmap的高速加载 (1)Bitmap是如何加载的?BitmapFactory类提供了四类方法:decodeFile.decodeResourc ...

  6. android 开发 View _12_ 用Canvas 绘制一张图片(博客中演示用Canvas画验证码图片)

    package net.yt.yuncare.widgets; import android.graphics.Bitmap; import android.graphics.Canvas; impo ...

  7. java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@412d7230

    近期遇到了如标题这种错误,再次记录解决方法.本文參考帖子: http://bbs.csdn.net/topics/390196217 出现此bug的原因是在内存回收上.里面用Bitamp的代码为: t ...

  8. Android java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@412d7230

    近期遇到了如标题这种错误,再次记录解决方法.本文參考帖子: http://bbs.csdn.net/topics/390196217 出现此bug的原因是在内存回收上.里面用Bitamp的代码为: t ...

  9. android开发里跳过的坑——“org.apache.http.message.BasicHeaderValueFormatter.INSTANCE”错误

    在android4.4.2的系统里,写了一个系统应用,其中有一个功能是通过表单上传图片的,使用了httpclient-4.5.3.jar httpmime-4.5.3.jar httpcore-4.4 ...

随机推荐

  1. python爬虫——拉钩网python岗位信息

    之前爬取的网页都是采用"GET"方法,这次爬取"拉勾网"是采取了"POST"的方法.其中,"GET"和"POS ...

  2. C++基础——文件逐行读取与字符匹配

    技术背景 用惯了python,对其他语言就比较的生疏.但是python很多时候在性能上比较受局限,这里尝试通过C++来实现一个文件IO的功能,看看是否能够比python的表现更好一些.关于python ...

  3. 字符串 前 L的含义

    转自http://blog.csdn.net/whz_zb/article/details/7446901 一. 在字符串前加一个L作用: unicode字符集是两个字节组成的.L告示编译器使用两个字 ...

  4. 测试报告$\alpha$

    pytorch可视化编程网站VisualPytorch NAG \(\alpha\)版本发布了!点击网址访问:VisualPytorch 一.测试查虫(bug detection) 测试贯穿了开发.集 ...

  5. Spring事务明明开启了,为什么没起作用???

    一.事务的特性(ACID) 1.原子性(Atomicity):事务是一个原子操作,由一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用. 2.一致性(Consistency):执行事务 ...

  6. Java Arrays.sort()重写comparator方法

    先看一下接口 Arrays.sort(T[],Comparator<? super T> c); comparator要重写compare方法 compare方法大概长这样,返回值> ...

  7. [bug] Flask:jinja2.exceptions.UndefinedError: 'None' has no attribute 'id'

    问题 Python Flask做的购物网站,添加购物车时,提示错误 解决 检查发现是MySQL中不正常的空数据导致,删除此条记录即可 参考 https://www.jb51.cc/python/186 ...

  8. inux软件安装管理之——dpkg与apt-*详解

    inux软件安装管理之--dpkg与apt-*详解 Nosee123关注 0.5922017.09.12 17:47:44字数 3,894阅读 8,565 [Linux软件安装管理系列]- - 传送门 ...

  9. qt利用QT designer构建第一个界面helloworld工程

    qt利用QT designer构建第一个界面helloworld工程原创ZJE_ANDY 发布于2017-04-07 20:25:28 阅读数 6613 收藏展开第一步:点击New Project 第 ...

  10. S7 Linux用户管理及用户信息查询命令

    7.1 useradd:创建用户 7.2-5 usermod 7.6 passwd:修改用户密码 7.7-9 chage.chpasswd.su 7.10-11 visudo.sudo 7.12-7. ...