开发者

Canvas: trying to use a recycled bitmap android.graphics.Bitmap

11-24 23:19:18.434: ERROR/AndroidRuntime(12660): Uncaught handler: thread main exiting due to uncaught exception
11-24 23:19:18.684: ERROR/AndroidRuntime(12660): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4384c218
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
11-24 23:19:18.684: ERROR/AndroidRuntime(开发者_运维问答12660):     at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:291)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.widget.ImageView.onDraw(ImageView.java:908)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.View.draw(View.java:6283)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.drawChild(ViewGroup.java:1581)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1311)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.drawChild(ViewGroup.java:1579)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1311)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.View.draw(View.java:6286)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.drawChild(ViewGroup.java:1581)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1311)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.widget.AbsListView.dispatchDraw(AbsListView.java:1323)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.widget.ListView.dispatchDraw(ListView.java:2933)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.View.draw(View.java:6389)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at         android.widget.AbsListView.draw(AbsListView.java:2142)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.drawChild(ViewGroup.java:1581)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1311)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.drawChild(ViewGroup.java:1579)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1311)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at     android.view.View.draw(View.java:6286)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.drawChild(ViewGroup.java:1581)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1311)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.View.draw(View.java:6286)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewGroup.drawChild(ViewGroup.java:1581)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at     android.view.ViewGroup.dispatchDraw(ViewGroup.java:1311)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.View.draw(View.java:6286)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1928)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewRoot.draw(ViewRoot.java:1454)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1174)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1774)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.os.Looper.loop(Looper.java:123)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at android.app.ActivityThread.main(ActivityThread.java:4321)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at java.lang.reflect.Method.invokeNative(Native Method)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at java.lang.reflect.Method.invoke(Method.java:521)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
11-24 23:19:18.684: ERROR/AndroidRuntime(12660):     at dalvik.system.NativeStart.main(Native Method)

I implemented an image cache with SoftReference and set an ImageView with a Bitmap from the image cache.

I do not use Bitmap.recycle() and check the Bitmap.isRcycled() before setting the bitmap to an ImageView.

I can not figure out why the canvas is drawing with a recycled bitmap. It happens rarely but it does happened.

Any suggestion? Thanks!


If anyone ever gets here and is struggling to figure out which Bitmap is recycled (like I did), here's what I ended up doing to troubleshoot this:
1) I placed a global Thread.setDefaultUncaughtExceptionHandler which dumps the heap (I actually already had it in place to diagnose OOM errors). The code inside the handler is this:

File f = new File(Environment.getExternalStorageDirectory(),"oom-error.hprof");
String path = f.getAbsolutePath();
// force a few GC before dumping stuff
System.gc();
System.gc();    
Debug.dumpHprofData(path);

2) Using this great article, you can learn how to then load up and analyze the hprof dump file using MAT.

3) Inside the MAT, I first filtered classes by "Bitmap" regex, and then looked for the Bitmap reference id (in OP case: "4384c218"). This will give you a pretty good idea which view is holding this recycled bitmap and you can start thinking of the solution for it. (In my case, I was recycling images from a common cache, some of which were drawables that were also used in XML layouts and should have been "pinned" to the cache until OnDestroy).


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.


The same problem, but now I have solved it. Try this way when reload a png or others:

BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.png1));

I must know when the png1 was recycled, if not, you can also try catch the RuntimeException exception.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜