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

一、Bitmap.recycle 方法被弃用

在Android中,Bitmap的存储分为两部分,一部分是Bitmap的数据,一部分是Bitmap的引用。在Android2.3时代,Bitmap的引用是放在堆中的,而Bitmap的数据部分是放在栈中的,需要用户调用recycle方法手动进行内存回收,而在Android2.3之后,整个Bitmap,包括数据和引用,都放在了堆中,这样,整个Bitmap的回收就全部交给GC了,这个recycle方法就再也不需要使用了。

下图是在Android系统源码里面截取的关于 recycle方法的说明:

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

可以发现,系统建议你不要手动去调用,而是让GC来进行处理不再使用的Bitmap。我们可以认为,即使在Android2.3之后的版本中去调用recycle,系统也是会强制回收内存的,只是系统不建议这样做而已。但是,当我们真这么天真的认为的时候,发现报错了,错误信息如下:

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1a50ff6b

二、问题的分析与解决

从日志可以很明显的看出,Bitmap被调用recycle方法回收后,又调用了Bitmap的一些方法而导致的。可是,代码中可以发现我们recycle的是bitmap而不是通过Bitmap.createBitmap重新生成的targetBmp,为什么会报这个exception呢?

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

里面有一句很重要的注释:

The new bitmap may be the same object as source, or a copy may have been made.

看来还是真有可能为同一个对象的!

解决方法:如果你的代码不需要兼容2.3版本的情况下,就别使用recycle了,还是交给GC处理吧。

上一篇:Salt Document学习笔记2


下一篇:JAVA中异常状况总结