0

I´m trying to solve a bug which it´s only throw in android 8 and 9. I´m looking in some post but they are old. I find in android doc solutions to android 3 and newer but I think this error it´s happening for something new. I´ve tried to resolve with the docs info but I can´t import some class, like 'RecyclingBitmapDrawable'

Here de android doc: https://developer.android.com/topic/performance/graphics/manage-memory#kotlin

And a post I read: Canvas: Trying to use a recycled bitmap error

I´m trying to control that bitmap error with this code.

companion object {
    private var bitmapResource: Bitmap? = null
    fun getCropBitmapResource(context: Context): Bitmap {
      if (bitmapResource == null) {
        bitmapResource = drawableResourceToBitmap(context, R.drawable.ic_select)
      }
      return bitmapResource!!
    }
}

fun drawableResourceToBitmap(context: Context, imageResource: Int): Bitmap {
      val drawable = AppCompatDrawableManager.get().getDrawable(context, imageResource)
      val bitmapResource = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
      val canvas = Canvas(bitmapResource)

      drawable.setBounds(0, 0, canvas.width, canvas.height)
      drawable.draw(canvas)
      return bitmapResource
}

Here the error

Canvas: trying to use a recycled bitmap android.graphics.Bitmap@73618ca
android.graphics.BaseCanvas.throwIfCannotDraw (BaseCanvas.java:62)
android.view.DisplayListCanvas.throwIfCannotDraw (DisplayListCanvas.java:226)
android.view.RecordingCanvas.drawBitmap (RecordingCanvas.java:98)
android.graphics.drawable.BitmapDrawable.draw (BitmapDrawable.java:545)
android.widget.ImageView.onDraw (ImageView.java:1360)
android.view.View.draw (View.java:20234)
android.view.View.updateDisplayListIfDirty (View.java:19109)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
android.view.View.draw (View.java:20237)
android.view.View.updateDisplayListIfDirty (View.java:19109)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw (ConstraintLayout.java:2023)
android.view.View.updateDisplayListIfDirty (View.java:19100)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
android.view.View.draw (View.java:20237)
android.view.View.updateDisplayListIfDirty (View.java:19109)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
android.view.View.draw (View.java:20237)
androidx.viewpager.widget.ViewPager.draw (ViewPager.java:2426)
android.view.View.updateDisplayListIfDirty (View.java:19109)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw (ConstraintLayout.java:2023)
android.view.View.draw (View.java:20237)
android.view.View.updateDisplayListIfDirty (View.java:19109)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
android.view.View.updateDisplayListIfDirty (View.java:19100)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
android.view.View.updateDisplayListIfDirty (View.java:19100)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
android.view.View.updateDisplayListIfDirty (View.java:19100)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
android.view.View.updateDisplayListIfDirty (View.java:19100)
android.view.View.draw (View.java:19962)
android.view.ViewGroup.drawChild (ViewGroup.java:4337)
android.view.ViewGroup.dispatchDraw (ViewGroup.java:4114)
android.view.View.draw (View.java:20237)
com.android.internal.policy.DecorView.draw (DecorView.java:784)
android.view.View.updateDisplayListIfDirty (View.java:19109)
android.view.ThreadedRenderer.updateViewTreeDisplayList (ThreadedRenderer.java:686)
android.view.ThreadedRenderer.updateRootDisplayList (ThreadedRenderer.java:692)
android.view.ThreadedRenderer.draw (ThreadedRenderer.java:801)
android.view.ViewRootImpl.draw (ViewRootImpl.java:3361)
android.view.ViewRootImpl.performDraw (ViewRootImpl.java:3158)
android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2527)
android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1500)
android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:7342)
android.view.Choreographer$CallbackRecord.run (Choreographer.java:1036)
android.view.Choreographer.doCallbacks (Choreographer.java:832)
android.view.Choreographer.doFrame (Choreographer.java:767)
android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:1022)
android.os.Handler.handleCallback (Handler.java:873)
android.os.Handler.dispatchMessage (Handler.java:99)
android.os.Looper.loop (Looper.java:201)
android.app.ActivityThread.main (ActivityThread.java:6810)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:547)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:873)

I don´t call recycle() in any part of my code.

  • you need to find `.recycle()` method in your source code and remove that or move it to more adequate place. – Rahul Oct 15 '19 at 13:29
  • I don´t use recycle() – Felipe Pereira Garcia Oct 15 '19 at 13:39
  • can you add this check `bitmapResource == null || bitmapResource.isRecycled()` – Rahul Oct 15 '19 at 13:45
  • that is not necessary. The doc says GC does this work good after android 3 – Felipe Pereira Garcia Oct 15 '19 at 14:18
  • well I can understand what you are saying but there is one widget (whichever could it be) is recycling your bitmap. It may be widget from android aosp, support or 3rd party library. So you need to check if bitmap is recycled, if yes, than you need to create another bitmap. Or you need to find out which is recycling your bitmap. You can do it by hooking debugger into Bitmap.recycle method. – Rahul Oct 15 '19 at 14:23
  • I can try to debug but this error is reported by crashlytics and it rarely happens, so when I debug nothing happen. Maybe I can try with `bitmapResource == null || bitmapResource.isRecycled()` to next release and waiting if the error persint – Felipe Pereira Garcia Oct 15 '19 at 14:35

1 Answers1

0

use this code for your convert

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.image);

you must use

BitmapFactory

for your converting.

Edited: same method in java, maybe help

public static Bitmap drawableToBitmap (Drawable drawable) {

if (drawable instanceof BitmapDrawable) {
    return ((BitmapDrawable)drawable).getBitmap();
}

Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), 
drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); 
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);

return bitmap;
}
alireza daryani
  • 787
  • 5
  • 16