在写瀑布流图片加载的时候出现了一个错误 java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap
从log可以找到错误的源头
@Override
protected void onDestroy() {
super.onDestroy();
// Bitmap对象回收掉
if (bitmap != null) {
bitmap.recycle();
}
}
这就意味着只有当你确认你不会在使用这个bitmap的时候,才可以选择调用recycle()方法释放它。
而我这里是使用了第三方的UIL图片加载库,它拥有完整的图片缓存机制,所以可能在未完全回收掉的时候使用了该bitmap
(这里亲测,如果加载了大图,没有立即回退,可能不会出现错误,如果马上回退,立即出错)
按照网上的写法,在自定义的view的onDraw方法中捕获异常:
@Override
protected void onDraw(Canvas canvas) {
try {
super.onDraw(canvas);
initBitmap(canvas);
}
catch (Exception e){
System.out.println("Canvas: trying to use a recycled bitmap");
}
}
发现依然出错,说白了自定义的View仍然持有bitmap,可能跟使用ImageLoader有关,不知道自己用BitmapFactory会咋样没试过。
解决的方案:在回收前,确定所有对bitmap的使用都停止了,如设置背景bitmap为空等操作setImageDrawable(null),setbackgroud(null);,具体情况具体分析。只有当你确认你不会在使用这个bitmap的时候,就可以选择调用recycle()方法释放它。
在网上看到的一段话:
我觉得该不该使用recycle方法,完全取决于你自己的水平,经测,我本人不适合,因为我在自己认为bitmap已经完全不会再使用的地方调用了recycle方法结果在某些条件下还是出现了上面的异常。所以recycle方法虽好,但是你要能够驾驭,而且一般情况下是不需要他的。
当你根据id从drawable(drawable资源文件夹)中获取一个drawable时,系统会将这个drawable加入缓存之中。这样,你第二次继续获取这个drawable时,如果缓存之中的drawable没有被回收,则会被返回。
如果你通过getDrawable(id)方法获取到一个bitmap1,继续通过getDrawable(id)方法获取到一个bitmap2。那么bitmap1=bitmap2。所以,当你对bitmap1进行recycle之后,又将bitmap2设置给Imageview显示,极大可能会出现java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@xxx的错误。