尝试使用回收的位图 android.graphics.Bitmap

3
我在我的Activity A中展示了一个.gif文件。当用户按下一个按钮后,用户将转移到Activity B,并且同一.gif文件也会在那里显示,但我在Activity B上遇到了“尝试使用已回收的位图android.graphics.Bitmap”这个错误。
我从SD卡中展示.gif,并在onStop()时还在Activity A中将imageview设置为null,但我无法解决这个问题。
请帮忙解决这个问题。
//日志Cat
12-31 10:58:49.819: E/AndroidRuntime(20903): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@405131c8
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.widget.ImageView.onDraw(ImageView.java:854)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.View.draw(View.java:6880)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.View.draw(View.java:6883)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.View.draw(View.java:6883)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.widget.FrameLayout.draw(FrameLayout.java:357)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.View.draw(View.java:6883)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.widget.FrameLayout.draw(FrameLayout.java:357)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1871)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewRoot.draw(ViewRoot.java:1542)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1269)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1883)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.os.Looper.loop(Looper.java:130)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at android.app.ActivityThread.main(ActivityThread.java:3737)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at java.lang.reflect.Method.invokeNative(Native Method)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at java.lang.reflect.Method.invoke(Method.java:507)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:894)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
12-31 10:58:49.819: E/AndroidRuntime(20903):     at dalvik.system.NativeStart.main(Native Method)

2
请展示一些你的代码和 logcat。 - Lawrence Choy
没有查看代码很难给你一个答案。但是发生的情况是这样的:当你将ImageView设置为null时,它可能会回收资源并回收位图。但是如果你在B活动中解码位图,就不应该出现这个错误。如果你的图片很大,而且你认为你会遇到OOM错误,那么请考虑使用位图选项,并将图像解码到ImageView的大小。 - Asanka Senavirathna
我假设你正在使用 Facebook 滑动库......这是因为在你所使用的滑出库中回收位图的缘故。我也遇到了同样的异常情况,并已成功修复它。 - Pragnani
3个回答

15

你可以在回收位图之前进行检查,例如:

if (img != null && !img.isRecycled()) 
{
 img.recycle(); 
 img = null;
 System.gc(); 
}

这里的img是位图。 尝试这样做,类型错误会被解决。


4
有时候我希望有权力“删除”某些用户,只是因为他们不接受一个答案! - JJ86
@RvPanchal,这段代码有什么问题?你能在这里解释一下吗? - Zala Janaksinh
@RvPanchal 可以在这里发布您的代码吗?因为我已经检查过了,如果Bitmap被回收,则将它们回收...只需检查您的代码。 - Zala Janaksinh
这是我的代码: if(bi != null && !bi.isRecycled()){ bi.recycle(); bi = null; } bi = mPdfPage.getImage((Constants.SCREEN_WIDTH * 2), (Constants.SCREEN_HEIGHT * 2), clip, true, true); // SaveBitmap(bi, str); return bi; - Ravi Makvana
只需创建可变位图就可以解决你的问题。因为你使用了不可变的位图再次进行修改,就像字符串一样。只需阅读一些关于可变与不可变位图的内容,你的问题就会得到解决。这并不是我的代码问题。 - Zala Janaksinh
我认为你不需要手动回收位图。从Android v3.0开始,它会在内部自动回收。另外一个要注意的是,你可以使用BitmapFactory.Options.inBitmapinSampleSize来解码更大的位图。 - Amol Desai

0

尝试在您的代码或使用的任何库中查找recycle()方法的使用参考。它表示有人正在回收仍在使用的位图,这是不好的。只有当您绝对确定给定的位图不再需要时,才可以安全地调用recycle()方法。

当您处理位图缓存时,通常会出现常见问题,不确定是否适用于您的情况。


我已经尝试使用recycle(),但这仅适用于Android中的2.3或更低版本。 - Ravi Makvana

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接