Android 尝试使用回收的位图,而不是在我的代码中

发布于 2024-11-25 20:13:54 字数 2968 浏览 1 评论 0原文

我每隔一段时间就会从市场开发者控制台得到这个堆栈跟踪;我找不到任何方法来重现该错误。当应用程序首次加载时显示闪屏 ImageView 时会发生这种情况,但堆栈跟踪没有我的任何代码。我什至认为我的活动还没有达到 onCreate,尽管没有日志很难判断。

事实上,我从未在代码中的任何地方真正使用过位图;我对图像的唯一引用是在我的layout.xml 中。

<ImageView android:id="@+id/splashScreen"
  android:layout_height="fill_parent"
  android:layout_width="fill_parent"
  android:src="@drawable/splashscreen"
  android:scaleType="fitXY"
/>

我对这个 ImageView 所做的唯一一件事就是在开始时将其可见性设置为 GONE。

我能做些什么吗?

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4721ec18
at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:323)
at android.widget.ImageView.onDraw(ImageView.java:923)
at android.view.View.draw(View.java:6761)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.View.buildDrawingCache(View.java:6517)
at android.view.View.getDrawingCache(View.java:6305)
at android.view.ViewGroup.drawChild(ViewGroup.java:1588)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1409)
at android.view.View.draw(View.java:6764)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.View.draw(View.java:6764)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.View.draw(View.java:6764)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1887)
at android.view.ViewRoot.draw(ViewRoot.java:1432)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1167)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1764)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:5068)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

I get this stacktrace from the Market developer console every once in a while; I can't find any way to repro the error. It's happening while displaying a splashscreen ImageView as the app is first loading, but the stacktrace doesn't have any of my code. I don't even think my activity has even reached onCreate, though it's hard to tell without a log.

Indeed, I never actually use a Bitmap anywhere in my code; my only reference to the image is in my layout.xml.

<ImageView android:id="@+id/splashScreen"
  android:layout_height="fill_parent"
  android:layout_width="fill_parent"
  android:src="@drawable/splashscreen"
  android:scaleType="fitXY"
/>

The only thing I do with this ImageView is set its visibility to GONE when I'm finished starting.

Is there anything I can do about this?

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4721ec18
at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:323)
at android.widget.ImageView.onDraw(ImageView.java:923)
at android.view.View.draw(View.java:6761)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.View.buildDrawingCache(View.java:6517)
at android.view.View.getDrawingCache(View.java:6305)
at android.view.ViewGroup.drawChild(ViewGroup.java:1588)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1409)
at android.view.View.draw(View.java:6764)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.View.draw(View.java:6764)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at android.view.ViewGroup.drawChild(ViewGroup.java:1663)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.ViewGroup.drawChild(ViewGroup.java:1661)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1390)
at android.view.View.draw(View.java:6764)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1887)
at android.view.ViewRoot.draw(ViewRoot.java:1432)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1167)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1764)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:5068)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

平生欢 2024-12-02 20:13:54

当您尝试回收或使用回收的位图时,会发生此异常。您不应该从现有代码中删除 bitmap.recycle() 函数,它可能会导致内存不足错误。您可以尝试下面的代码来解决该问题。

BitmapDrawable bitmapDrawable = ((BitmapDrawable) profileWallpaper.getDrawable());

                if (null != bitmapDrawable && !bitmapDrawable.getBitmap().isRecycled()) {

                    bitmapDrawable.getBitmap().recycle();
                } else {

                    log("bitmap is already recycled");
                }

                bitmapDrawable = null;

注意:profileWallpaper 是您的 imageView 对象

This exception occurs when you try to recycle or use a recycled bitmap. You should not remove bitmap.recycle() function from your existing code, it may cause Out Of Memory Error. You can try this below code to fix the issue.

BitmapDrawable bitmapDrawable = ((BitmapDrawable) profileWallpaper.getDrawable());

                if (null != bitmapDrawable && !bitmapDrawable.getBitmap().isRecycled()) {

                    bitmapDrawable.getBitmap().recycle();
                } else {

                    log("bitmap is already recycled");
                }

                bitmapDrawable = null;

Note: profileWallpaper is your imageView object

永不分离 2024-12-02 20:13:54

如果您在代码中的某个位置回收位图,您应该确保当应用程序重新启动时,您的位图将被重新创建。
当您通过onCreate时,没有问题,但是当应用程序暂停并重新启动时,它将不会再次通过onCreate,而只是通过onResume。
我认为您可以在 onResume 方法中重新创建位图,但使用标志在 onCreate 或 onResume 中创建位图,而不是两者(onCreate 和 onResume 在应用程序启动时一起调用,您可能会浪费 CPU 周期)。

If you recycle your bitmap somewhere in your code, you should be sure that, when the app restart, your bitmap would be recreated.
When you pass through the onCreate, no issues, but when the app is in pause and restarted it will not pass through the onCreate again, just through the onResume.
I think you could recreate your bitmaps in the onResume method, but use a flag to create the bitmap in the onCreate or in the onResume, not both (onCreate and onResume are called together when the app starts and you could waste CPU cycles).

黎夕旧梦 2024-12-02 20:13:54

当其中一个活动正在回收其位图时,您不应将相同的图像资源用于不同的活动。

如果您遇到这种情况,请更改其中一项活动的图像资源。

You should not use same image resources for different Activities while one of them is recycling its bitmap.

If you have this situation, changed the image resource of one of those Activities.

许久 2024-12-02 20:13:54

您是否尝试过降低图像的清晰度?这种事在我身上发生过很多次。如果调整图像大小后问题仍然存在,则意味着问题出在其他地方......我会在主要活动的 on create 方法或闪屏代码中查看。

对不起,我蹩脚的英语:)

C ya!

Have you tried to lower the ress of the image? It happened to me lots of times. If the problem continues after rezise the image, it means that the problem is in somewere else... I would look in the on create methode from your main activity or in the splashscreen code.

sorry my crappy english :)

C ya!

总攻大人 2024-12-02 20:13:54

刚刚用类似的崩溃日志解决了问题。就我而言,它只是片段内的第二个进度条。我里面有两个列表,每个列表都有进度条。删除第二个就解决了这个问题。我只能猜测他们使用相同的位图资源作为背景或动画......

我花了很多时间来理解它的原因,它只是一个标准的进度条! :/
希望这可以帮助某人节省时间并安心。

Just solved the issue with similar crash log. In my case it was just second ProgressBar inside the fragment. I had two lists inside it and ProgressBars for each of them. Removing the second one solved the problem. I can only guess that they were using the same bitmap resource for background or animation...

I've spent a lot of time to understand its reason, and it was just a standart ProgressBar! :/
Hope this help someone to save the time and peace of mind.

無心 2024-12-02 20:13:54

我遇到了并非来自我的应用程序的相同异常,并且发现它与 AdMob 无关。

当您回收通过 XML 设置到 ImageViewBitmapDrawable 资源时,就会出现此问题。

恢复时,无论图像是否被回收,Android 都不会再次解码图像,因此,您将收到 Canvas: attempts to use a returned bitmap

解决这个问题的方法是在ActivityonPause处重新加载相应的BitmapDrawable,这样android就不会抱怨位图被回收了。

操作方法如下:

Bitmap selectImage = BitmapFactory.decodeResource(getResources(), R.drawable.your_bitmap_drawable);
yourImageView.setImageBitmap(selectImage);

编辑:
我意识到只需将 yourImageViewDrawable 设置为 null 也可以防止此错误。只是不要留下具有回收的位图Drawable。示例代码:

yourImageView.setImageDrawable(null);

I was having the same Exception that is not coming from my application and found out that it is not related to AdMob.

The issue arises when you recycle a BitmapDrawable resource that was set through XML to your ImageView.

While resuming, android doesn't decode the image again whether it is recycled or not, therefore, you are getting Canvas: trying to use a recycled bitmap.

The way to get solve this issue is to reload the corresponding BitmapDrawable at onPause of your Activity so that android would not complain about the bitmap being recyced.

Here is how to do it:

Bitmap selectImage = BitmapFactory.decodeResource(getResources(), R.drawable.your_bitmap_drawable);
yourImageView.setImageBitmap(selectImage);

Edit:
I realized simply setting Drawable of yourImageView to null also prevents this error. Just don't leave a Drawable that has a recycled Bitmap. Example code:

yourImageView.setImageDrawable(null);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文