Android开发回收bitmap引发Canvas: trying to use a recycled bitmap错误处理
当你的应用由于加载大量图片出现OOM异常时,肯定会上网搜索关于OOM的文章,并导求相应的解决方案,比如压缩图片大小,或手动回收资源什么的。在这里我们不讨论图片压缩或缓冲这些方法,而是讨论一下手动回收BITMAP时可能出现的问题,亦即 Canvas: trying to use a recycled bitmap。
很容易可以预料到,你必然会遇到并使用如下代码:
- if(bitmap != null && !bitmap.isRecycled()){
- bitmap.recycle(); //此句造成的以上异常
- bitmap = null;
- }
- 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错误处理的更多相关文章
- Android手动回收bitmap,引发Canvas: trying to use a recycled bitmap处理
在做Android的开发的时候,在ListView 或是 GridView中需要加载大量的图片,为了避免加载过多的图片引起OutOfMemory错误,设置了一个图片缓存列表 Map<String ...
- Android Bitmap操作问题之Canvas: trying to use a recycled bitmap
一.Bitmap.recycle 方法被弃用 在Android中,Bitmap的存储分为两部分,一部分是Bitmap的数据,一部分是Bitmap的引用.在Android2.3时代,Bitmap的引用是 ...
- Canvas: trying to use a recycled bitmap android.graphics.Bitmap@XXX
近期在做和图片相关显示的出现了一个问题,整理一下思路.分享出来给大家參考一下: Exception Type:java.lang.RuntimeException java.lang.RuntimeE ...
- 《android开发艺术探索》读书笔记(十二)--Bitmap的加载和Cache
接上篇<android开发艺术探索>读书笔记(十一)--Android的线程和线程池 No1: 目前比较常用的缓存策略是LruCache和DiskLruCache,LruCache常被用作 ...
- Android开发艺术探索》读书笔记 (12) 第12章 Bitmap的加载和Cache
第12章 Bitmap的加载和Cache 12.1 Bitmap的高速加载 (1)Bitmap是如何加载的?BitmapFactory类提供了四类方法:decodeFile.decodeResourc ...
- android 开发 View _12_ 用Canvas 绘制一张图片(博客中演示用Canvas画验证码图片)
package net.yt.yuncare.widgets; import android.graphics.Bitmap; import android.graphics.Canvas; impo ...
- java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@412d7230
近期遇到了如标题这种错误,再次记录解决方法.本文參考帖子: http://bbs.csdn.net/topics/390196217 出现此bug的原因是在内存回收上.里面用Bitamp的代码为: t ...
- Android java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@412d7230
近期遇到了如标题这种错误,再次记录解决方法.本文參考帖子: http://bbs.csdn.net/topics/390196217 出现此bug的原因是在内存回收上.里面用Bitamp的代码为: t ...
- android开发里跳过的坑——“org.apache.http.message.BasicHeaderValueFormatter.INSTANCE”错误
在android4.4.2的系统里,写了一个系统应用,其中有一个功能是通过表单上传图片的,使用了httpclient-4.5.3.jar httpmime-4.5.3.jar httpcore-4.4 ...
随机推荐
- Go 函数详解
一.函数基础 函数由函数声明关键字 func.函数名.参数列表.返回列表.函数体组成 函数是一种类型.函数类型变量可以像其他类型变量一样使用,可以作为其他函数的参数或返回值,也可以直接调用执行 函数名 ...
- [DB] Hadoop免密登录原理及设置
情景: 现有两台电脑bigdata111.bigdata112,bigdata111想免密码登录bigdata112 过程: 1.bigdata111生成公钥(用于加密,给别人)和私钥(用于解密,自己 ...
- ipmitool -I lanplus -H 10.1.81.90 -U admin -P admin mc reset cold
ipmitool -I lanplus -H 10.1.81.90 -U admin -P admin mc reset cold
- 使用LUKS加密你的磁盘
计算机数据的安全,保密性在现在的生活中显得越来越重要.随着数字化的时代的来临,越来越多的数据被数字化,特别是更多有关于我们隐私的数据在不断生成,甚至还有我们需要离线保存的密钥等.而且通常我们使用磁盘, ...
- 1.1Ubuntu安装
在虚拟机中安装 Ubuntu 步骤 安装前的准备和基本安装 设置语言环境 安装常用软件 1. 安装前的准备和基本安装 1.1 安装前的准备 访问 http://cn.ubuntu.com/downlo ...
- 链表中倒数第k个节点 双指针
- HTML 标签隐藏占用空间与不占用空间(Day_29)
老是有些忘记或者搞混淆,今天写篇博客. 隐藏占用空间: 将标签的属性设置为: visibility:hidden; <input id="modifId" type=&quo ...
- Java中生成唯一标识符的方法
有时候业务需要生成唯一标识符,但又不能依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,此时我们就需要用程序来生成一个唯一的全局ID. UUID UUID是指在一台机器上 ...
- python实现给字典添加条目的方法
具体实现方法如下: def addWord(theIndex,word,pagenumber): theIndex.setdefault(word, [ ]).append(pagenumber)#存 ...
- 详述盒子模型(包含padding、border、margin的详细用法和描述)
提起盒子模型,我想无论是对于一个前端资深开发人员还是前端入门开发人员来说都不陌生,这是CSS最基础的知识. 但是惭愧地说,我之前理解的盒子模型,只是文字上的理解.我知道定义一个元素的宽度和高度时,设置 ...