20

我的应用程序可以加载相当大的图像。为了节省内存,我尝试使用一个临时位图来加载,另一个用于转换后的最终图像:

.....
finalBitmap.recycle();
finalBitmap = null;
Bitmap tempBitmap  = BitmapFactory.decodeStream(fin, ...);
finalBitmap = Bitmap.createBitmap(tempBitmap, ....);
imgview.setImageBitmap(finalBitmap);
.....

现在,此时我们已经完成了 tempBitmap,它只需要将解码的 Bitmap 传输到 createBitmap 中的转换步骤。所以:

.....
tempBitmap.recycle();
tempBitmap = null;
.....

并且...它因“尝试使用回收的位图”错误而崩溃,具体是因为 tempBitmap 的回收。tempBitmap 未显示,仅在此处使用。

这里出了什么问题?我是否应该始终使用“finalBitmap”并依靠 createBitmap 来管理它(finalBitmap = Bitmap.createBitmap( finalBitmap , ....))?我看不到对 tempBitmap 的持续依赖会导致这样的失败。

编辑:是的,空赋值似乎会导致适当的最终垃圾收集,但我很困惑为什么临时位图上的 recycle() 在这种情况下会出现问题。我得到的印象是 createBitmap() 持有对它的引用,但为什么,以及持续多长时间?

4

1 回答 1

25

直接来自 Android文档

从源位图的指定子集中返回不可变位图。新位图可能是与源相同的对象,或者可能已经制作了副本。

似乎 createBitmap 函数有可能重新使用您提供的位图。如果是这种情况,那么您不应该回收临时位图,因为您的最终位图正在使用它。你可以做的一件事是

if(tempBitmap != finalBitmap) {
   tempBitmap.recycle();
}

那应该只在它与 finalBitmap 不同时回收 tempBitmap。至少这似乎是文档所暗示的。

于 2011-11-02T17:01:31.907 回答