Android:临时位图的“尝试使用回收的位图”错误

Posted

技术标签:

【中文标题】Android:临时位图的“尝试使用回收的位图”错误【英文标题】:Android: "trying to use a recycled bitmap" error with temporary Bitmaps 【发布时间】:2011-12-20 11:09:05 【问题描述】:

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

.....
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() 持有对它的引用,但为什么,以及持续多长时间?

【问题讨论】:

【参考方案1】:

直接来自安卓documentation:

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

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

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

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

【讨论】:

我错过了关于它可能是同一个对象的一点。我将 temp 设置为 null 不会产生副作用,因为它并没有真正释放对象,而 recycle() 直接影响它。唔。我接受你的回答,并希望你能帮我支持我的问题(因为我认为这对人们来说是一个有用的信息)。

以上是关于Android:临时位图的“尝试使用回收的位图”错误的主要内容,如果未能解决你的问题,请参考以下文章

Android Dev:从存储在 SD 卡上的临时文件创建位图,设置 ImageView,然后将其存储在本地

Android 位图到 Base64 字符串

对(可能的)Android 内存泄漏一无所知

android 为啥我创建的临时文件名里有一串随机数

Android:将大位图放在小位图后面,大位图应形成小位图

Android - 用颜色填充位图