glide
glide copied to clipboard
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@ea5bf3d
Hi Glide team,
Recently after app release we started seeing this issue for few users.
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@ea5bf3d
The glide that we are using is com.github.bumptech.glide:glide:4.11.0
the retrofit library that we are using is com.squareup.retrofit2:retrofit:2.9.0
Following is the code snippet I am using for loading a image using glide into imageView
context?.let { context ->
Glide.with(context)
.load(story.url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.placeholder(binding.ivStory.drawable)
.listener(object: RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
return false
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
binding.loader.visibility = View.GONE
animation.start()
return false
}
}
)
.into(binding.ivStory)
The error that I am getting on firebase is as follows
Fatal Exception: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@d7a7131
at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:55)
at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:234)
at android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529)
at android.widget.ImageView.onDraw(ImageView.java:1376)
at android.view.View.draw(View.java:19442)
at android.view.View.updateDisplayListIfDirty(View.java:18392)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1975)
at android.view.View.draw(View.java:19445)
at android.view.View.updateDisplayListIfDirty(View.java:18392)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1975)
at android.view.View.updateDisplayListIfDirty(View.java:18383)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1975)
at android.view.View.draw(View.java:19445)
at android.view.View.updateDisplayListIfDirty(View.java:18392)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at android.view.View.updateDisplayListIfDirty(View.java:18383)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at android.view.View.updateDisplayListIfDirty(View.java:18383)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at androidx.drawerlayout.widget.DrawerLayout.drawChild(DrawerLayout.java:1426)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at android.view.View.draw(View.java:19445)
at android.view.View.updateDisplayListIfDirty(View.java:18392)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at android.view.View.updateDisplayListIfDirty(View.java:18383)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at android.view.View.updateDisplayListIfDirty(View.java:18383)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at android.view.View.updateDisplayListIfDirty(View.java:18383)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at android.view.View.updateDisplayListIfDirty(View.java:18383)
at android.view.View.draw(View.java:19170)
at android.view.ViewGroup.drawChild(ViewGroup.java:4324)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087)
at android.view.View.draw(View.java:19445)
at com.android.internal.policy.DecorView.draw(DecorView.java:892)
at android.view.View.updateDisplayListIfDirty(View.java:18392)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:676)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:682)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:790)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3503)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3285)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2782)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1718)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7513)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1066)
at android.view.Choreographer.doCallbacks(Choreographer.java:878)
at android.view.Choreographer.doFrame(Choreographer.java:794)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1052)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:210)
at android.app.ActivityThread.main(ActivityThread.java:7080)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:523)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:863)
Can you please help me understand what I am doing wrong here; Or if i can replace/improve this code to avoid this issue
Have you solved this problem
I have a similar problem too, which is occurred after user opening app from background.
- Glide version: 4.16.0
It's expected to set ImageView's imageDrawable null, if the Bitmap in Drawable the ImageView holds is recycled. But obviously, here the Drawable that ImageView holds is not set null.
I don't know whether system or Glide recycled that Bitmap.
The following is the code:
fun ImageView.setTransformedImageBitmap(
imageUrl: String?,
transformation: Transformation<Bitmap>,
currentUrlFetcher: () -> String?
) {
Glide.with(this)
.asBitmap()
.load(imageUrl)
.transform(transformation)
.transform(WebpDrawable::class.java, WebpDrawableTransformation(transformation))
.transition(BitmapTransitionOptions.withCrossFade())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.listener(
object : RequestListener<Bitmap> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Bitmap>,
isFirstResource: Boolean
): Boolean {
e?.run {
// some error logic
}
return false
}
override fun onResourceReady(
resource: Bitmap,
model: Any,
target: Target<Bitmap>,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
val currentUrl = currentUrlFetcher()
val resourceValid = !resource.isRecycled
if (currentUrl != imageUrl) {
Log.e(TAG, "Image url are inconsistent!")
return true
}
if (!resourceValid) {
Log.e(TAG, "Resource invalid!")
return true
}
return false
}
}
)
.into(this)
}
@Madderate were you able to find a fix for this? having a similar issue when a user opens the app from the background as well