Canvas: попытка использования переработанного растрового изображения 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) 

Я реализовал кеш изображения с SoftReference и установил ImageView с растровым изображением из кэша изображений.

Я не использую Bitmap.recycle () и проверяю Bitmap.isRcycled () перед установкой растрового изображения в ImageView.

Я не могу понять, почему холст рисует с использованием переработанного растрового изображения. Это случается редко, но это случается.

Любое предложение? Благодаря!

Если кто-нибудь когда-нибудь придет сюда и изо всех сил пытается выяснить, какой Bitmap перерабатывается (как и я), вот что я сделал для устранения этой проблемы:
1) Я поместил глобальный Thread.setDefaultUncaughtExceptionHandler который выгружает кучу (у меня на самом деле уже было место для диагностики ошибок OOM). Код внутри обработчика таков:

 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) Используя эту замечательную статью, вы можете узнать, как загрузить и проанализировать файл дампа hprof с помощью MAT .

3) Внутри MAT я сначала отфильтровал классы по регулярному выражению «Bitmap», а затем искал идентификатор ссылки Bitmap (в случае OP: «4384c218»). Это даст вам довольно хорошую идею, которая рассматривает этот переработанный растровый рисунок, и вы можете начать думать о решении для него. (В моем случае я перерабатывал изображения из общего кеша, некоторые из которых были drawables, которые также использовались в XML-макетах и ​​должны были быть «закреплены» в кеше до OnDestroy).

Вы не должны использовать одни и те же ресурсы изображения для разных видов деятельности, в то время как один из них перерабатывает его растровое изображение.

Если у вас возникла такая ситуация, изменился ресурс изображения одного из этих действий.

Та же проблема, но теперь я ее решил. Попробуйте это при перезагрузке png или других:

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

Я должен знать, когда png1 был переработан, если нет, вы также можете попытаться поймать исключение RuntimeException.