定位Canvas: trying to use a recycled bitmap android.graphics.Bitmap@299c9ae7
来源:互联网 发布:windows下的串口编程 编辑:程序博客网 时间:2024/06/05 20:05
在工作中碰到这样一个问题,描述为:设置计时器,等待计时器时间到按Home退出,重启手机后,解锁时SystemUI报错。(实际和计时器毫无关系,插入USB重启后就会报错)
查看LOG如下:
AndroidRuntime: Shutting down VMAndroidRuntime: FATAL EXCEPTION: mainAndroidRuntime: Process: com.android.systemui, PID: 1224java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@299c9ae7 at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1282) at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:599) at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:538) at android.view.View.getDrawableRenderNode(View.java:15766) at android.view.View.drawBackground(View.java:15712) at android.view.View.draw(View.java:15479) at android.widget.FrameLayout.draw(FrameLayout.java:658) at android.view.View.updateDisplayListIfDirty(View.java:14384) at android.view.View.getDisplayList(View.java:14413) at android.view.View.draw(View.java:15204) at android.view.ViewGroup.drawChild(ViewGroup.java:3532) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325) at android.view.View.draw(View.java:15507) at android.widget.FrameLayout.draw(FrameLayout.java:658) at android.view.View.updateDisplayListIfDirty(View.java:14384) at android.view.View.getDisplayList(View.java:14413) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:279) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:285) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:335) at android.view.ViewRootImpl.draw(ViewRootImpl.java:2939) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2753) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2367) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1292) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6598) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800) at android.view.Choreographer.doCallbacks(Choreographer.java:603) at android.view.Choreographer.doFrame(Choreographer.java:572) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5666) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
以上LOG中仅仅能够看到是使用了已经回收的图片,但是图片在哪使用,在哪回收无法从LOG中获取,而且现象是偶现。即使再次复现也是同样的LOG,无法追究到根本原因。网上也有很多关于类似问题的帖子,大多数都是自己开发的应用,清楚的知道手动调用recycle()的位置,或者去除或者采用其他方式。针对这个问题,问题就在于不知到系统哪里回收了图片。
1. 经过不断的尝试排除,最终基本找到了问题的必现路径。
2. 咨询其他员工,添加打印栈的信息。
在frameworks/base/graphics/java/android/graphics/Bitmap.java中public void recycle() { /**增加以下LOG,打印出被回收图片的hash值*/ Log.d("BitmapTAG", "Object tried to call recycle,this="+this)); /**增加以下方法,打印栈信息*/ Thread.dumpStack(); if (!mRecycled && mFinalizer.mNativeBitmap != 0) { if (nativeRecycle(mFinalizer.mNativeBitmap)) { // return value indicates whether native pixel object was actually recycled. // false indicates that it is still in use at the native level and these // objects should not be collected now. They will be collected later when the // Bitmap itself is collected. mBuffer = null; mNinePatchChunk = null; } mRecycled = true; }}
因为问题必现,所以很容易抓取加入信息后的报错LOG。
通过过滤发现,被回收的LOG有很多,如下:
BitmapTAG: Object tried to call recycle,this=android.graphics.Bitmap@30b0ce56BitmapTAG: Object tried to call recycle,this=android.graphics.Bitmap@299c9ae7BitmapTAG: Object tried to call recycle,this=android.graphics.Bitmap@2b8b32adBitmapTAG: Object tried to call recycle,this=android.graphics.Bitmap@2e708e18.......
还有很多,不过只需要@299c9ae7这一个就好。
过滤tag为BitmapTAG|System.err的LOG发现了 299c9ae7
D/BitmapTAG(1224): Object tried to call recycle,this=android.graphics.Bitmap@299c9ae7W/System.err(1224): java.lang.Throwable: stack dumpW/System.err(1224): at java.lang.Thread.dumpStack(Thread.java:490)W/System.err(1224): at android.graphics.Bitmap.recycle(Bitmap.java:309)W/System.err(1224): at com.android.systemui.ImageWallpaper$DrawableEngine.trimMemory(ImageWallpaper.java:165)W/System.err(1224): at com.android.systemui.ImageWallpaper.onTrimMemory(ImageWallpaper.java:94)W/System.err(1224): at android.app.ActivityThread.handleTrimMemory(ActivityThread.java:4573)W/System.err(1224): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1666)W/System.err(1224): at android.os.Handler.dispatchMessage(Handler.java:111)W/System.err(1224): at android.os.Looper.loop(Looper.java:194)W/System.err(1224): at android.app.ActivityThread.main(ActivityThread.java:5666)W/System.err(1224): at java.lang.reflect.Method.invoke(Native Method)W/System.err(1224): at java.lang.reflect.Method.invoke(Method.java:372)W/System.err(1224): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)W/System.err(1224): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
可以看出是ImageWallpaper.java:的94行调用了recycle()
public void trimMemory(int level) { if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW && mBackground != null) { if (DEBUG) { Log.d(TAG, "trimMemory"); } mBackground.recycle(); mBackground = null; mBackgroundWidth = -1; mBackgroundHeight = -1; mWallpaperManager.forgetLoadedWallpaper(); } }
找到对应的代码注释掉即可。
0 0
- 定位Canvas: trying to use a recycled bitmap android.graphics.Bitmap@299c9ae7
- Canvas: trying to use a recycled bitmap android.graphics.Bitmap
- Canvas: trying to use a recycled bitmap android.graphics.Bitmap
- Android Bitmap回收异常:Canvas: trying to use a recycled bitmap android.graphics.Bitmap解决
- 【Bitmap】Canvas: trying to use a recycled bitmap android.graphics.Bitmap问题
- Bitmap的recycle后Canvas: trying to use a recycled bitmap android.graphics.Bitmap问题
- 解决Bitmap recycle异常:Canvas: trying to use a recycled bitmap android.graphics.Bitmap
- 今天遇到Canvas: trying to use a recycled bitmap android.graphics.Bitmap问题
- java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41a7f048
- java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@412d7230
- Canvas: trying to use a recycled bitmap android.graphics.Bitmap@XXX
- java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap...
- Gesture控制图片缩放&Canvas: trying to use a recycled bitmap android.graphics.Bitmap异常
- java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@412d723
- 分析Canvas: trying to use a recycled bitmap android.graphics.Bitmap@84709c2
- 关于异常Canvas: trying to use a recycled bitmap android.graphics.Bitmap的解决
- java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@358df999
- Bitmap回收—Canvas: trying to use a recycled bitmap android.graphics
- 最原始的CD转换mp3。
- Class.forName()和classloader.loadclass()区别
- Distinct自定义去重
- 中序遍历二叉树——递归
- activity的横竖屏切换
- 定位Canvas: trying to use a recycled bitmap android.graphics.Bitmap@299c9ae7
- [leetcode323]Number of Connected Components in an Undirected Graph
- 集合栈
- tinyalsa 与 audioroute
- Python3.5 Django1.9.2常用命令
- 解决:ERROR ITMS-90023: "Missing required icon file. The bundle does not contain an app icon for iPad o
- System.out.println内容写入txt
- linux命令详解
- A different object with the same identifier value was already associated with the session