【问题标题】:Recycle bitmap throw error android 8 and 9回收位图抛出错误android 8和9
【发布时间】:2019-10-15 13:22:12
【问题描述】:

我正在尝试解决仅在 android 8 和 9 中出现的错误。我正在查看一些帖子,但它们已经过时了。我在 android doc 解决方案中找到了 android 3 和更新版本,但我认为这个错误是因为一些新的东西而发生的。我尝试使用文档信息解决,但我无法导入某些类,例如“RecyclingBitmapDrawable”

这里是安卓文档:https://developer.android.com/topic/performance/graphics/manage-memory#kotlin

我读过的一篇文章: Canvas: Trying to use a recycled bitmap error

我正在尝试使用此代码控制位图错误。

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
}

这里是错误

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)

我不会在代码的任何部分调用 recycle()。

【问题讨论】:

  • 您需要在源代码中找到.recycle() 方法并将其删除或移动到更合适的位置。
  • 我不使用 recycle()
  • 可以加这张支票吗bitmapResource == null || bitmapResource.isRecycled()
  • 这不是必需的。文档说 GC 在 android 3 之后做得很好
  • 嗯,我能理解你在说什么,但是有一个小部件(无论它是什么)正在回收你的位图。它可能是来自 android aosp、support 或 3rd 方库的小部件。因此,您需要检查位图是否被回收,如果是,则需要创建另一个位图。或者您需要找出哪个正在回收您的位图。您可以通过将调试器挂钩到 Bitmap.recycle 方法来做到这一点。

标签: android kotlin


【解决方案1】:

将此代码用于您的转换

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

你必须使用

位图工厂

为了您的转换。

编辑: java中的相同方法,也许有帮助

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;
}

【讨论】:

  • 这不起作用,返回 null。文档说“返回解码的位图,如果图像无法解码,则返回 null。”
  • 在这种情况下,请尝试另一个可绘制图像。我认为您的图像有问题
  • 试试这个,如果有帮助就更新我,stackoverflow.com/a/24389104/10608556
  • 我就是这样做的,唯一不同的是我如何获取Drawable,val drawable = AppCompatDrawableManager.get().getDrawable(context, imageResource) 你认为这是问题吗?
  • 为什么不使用getResource?
猜你喜欢
  • 2015-07-18
  • 2015-06-21
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2011-12-20
相关资源
最近更新 更多