bumptech / glide

An image loading and caching library for Android focused on smooth scrolling
https://bumptech.github.io/glide/
Other
34.64k stars 6.12k forks source link

IllegalStateException: Already released #4497

Open renaudcerrato opened 3 years ago

renaudcerrato commented 3 years ago

Glide Version: 4.11.0 and 4.12.0

Integration libraries: okhttp3-integration

Device/Android Version: Oppo/Lollipop (unable to reproduce on my Pixel / Android 10)

Repro steps: back and forth between activities and fragments. It can take a while.

Glide load line:

val options = RequestOptions().placeholder(defaultRes).error(defaultRes).let {
            if (roundCorners) it.transform(RoundedCorners(4.dp)) else it
        }

Glide.with(fragment).load(model).apply(options).into(CompositeBadgeViewTarget(view))

class CompositeBadgeViewTarget(view: CompositeBadgeView) : CustomViewTarget<CompositeBadgeView, Drawable>(view) {

    override fun onLoadFailed(errorDrawable: Drawable?) {
        view.badge.background = view.getDrawable(R.drawable.rounded_rectangle_surface200)
        view.badge.icon = errorDrawable
        view.badge.color = view.resolveThemeColorOrThrow(R.attr.colorSurface400)
    }

    override fun onResourceCleared(placeholder: Drawable?) {
        view.badge.background = null
        view.badge.icon = null
    }

    override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
        view.badge.background = resource
        view.badge.icon = null
    }

}

Stack trace / LogCat:

java.lang.RuntimeException: Unable to resume activity \{com.*/*.ui.home.HomeActivity\}: java.lang.IllegalStateException: Already released\
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3334)\
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3365)\
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1574)\
        at android.os.Handler.dispatchMessage(Handler.java:111)\
        at android.os.Looper.loop(Looper.java:210)\
        at android.app.ActivityThread.main(ActivityThread.java:5839)\
        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:1113)\
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:879)\
     Caused by: java.lang.IllegalStateException: Already released\
        at com.bumptech.glide.util.pool.StateVerifier$DefaultStateVerifier.c(SourceFile:2)\
        at com.bumptech.glide.load.engine.EngineJob.c(SourceFile:1)\
        at com.bumptech.glide.load.engine.Engine.l(SourceFile:2)\
        at com.bumptech.glide.load.engine.Engine.f(SourceFile:6)\
        at com.bumptech.glide.request.SingleRequest.e(SourceFile:24)\
        at com.bumptech.glide.request.target.CustomViewTarget$SizeDeterminer.d(SourceFile:4)\
        at com.bumptech.glide.request.target.CustomViewTarget.n(SourceFile:1)\
        at com.bumptech.glide.request.SingleRequest.f(SourceFile:19)\
        at com.bumptech.glide.manager.RequestTracker.f(SourceFile:4)\
        at com.bumptech.glide.RequestManager.x(SourceFile:1)\
        at com.bumptech.glide.RequestManager.b(SourceFile:1)\
        at com.bumptech.glide.manager.ActivityFragmentLifecycle.d(SourceFile:3)\
        at com.bumptech.glide.manager.SupportRequestManagerFragment.D1(SourceFile:2)\
        at androidx.fragment.app.Fragment.c2(SourceFile:5)\
        at androidx.fragment.app.FragmentStateManager.v(SourceFile:3)\
        at androidx.fragment.app.FragmentStateManager.m(SourceFile:9)\
        at androidx.fragment.app.FragmentStore.r(SourceFile:3)\
        at androidx.fragment.app.FragmentManager.P0(SourceFile:6)\
        at androidx.fragment.app.FragmentManager.T(SourceFile:3)\
        at androidx.fragment.app.FragmentManager.S(SourceFile:4)\
        at androidx.fragment.app.Fragment.c2(SourceFile:10)\
        at androidx.fragment.app.FragmentStateManager.v(SourceFile:3)\
        at androidx.fragment.app.FragmentStateManager.m(SourceFile:9)\
        at androidx.fragment.app.FragmentStore.r(SourceFile:3)\
        at androidx.fragment.app.FragmentManager.P0(SourceFile:6)\
        at androidx.fragment.app.FragmentManager.T(SourceFile:3)\
        at androidx.fragment.app.FragmentManager.S(SourceFile:4)\
        at androidx.fragment.app.FragmentController.q(SourceFile:1)\
        at androidx.fragment.app.FragmentActivity.onStart(SourceFile:9)\
        at androidx.appcompat.app.AppCompatActivity.onStart(SourceFile:1)\
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1244)\
        at android.app.Activity.performStart(Activity.java:6193)\
        at android.app.Activity.performRestart(Activity.java:6250)\
        at android.app.Activity.performResume(Activity.java:6255)\
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3319)\
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3365)\'a0\
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1574)\'a0\
        at android.os.Handler.dispatchMessage(Handler.java:111)\'a0\
        at android.os.Looper.loop(Looper.java:210)\'a0\
        at android.app.ActivityThread.main(ActivityThread.java:5839)\'a0\
        at java.lang.reflect.Method.invoke(Native Method)\'a0\
        at java.lang.reflect.Method.invoke(Method.java:372)\'a0\
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1113)\'a0\
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:879)\'a0\
02-04 03:41:28.874 31194-31194/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.<hidden>.stage.application, PID: 31194
    java.lang.IllegalArgumentException: Cannot add callbacks to a cancelled EngineJob
        at com.bumptech.glide.util.Preconditions.a(SourceFile:1)
        at com.bumptech.glide.load.engine.EngineJob.c(SourceFile:9)
        at com.bumptech.glide.load.engine.Engine.l(SourceFile:2)
        at com.bumptech.glide.load.engine.Engine.f(SourceFile:6)
        at com.bumptech.glide.request.SingleRequest.e(SourceFile:24)
        at com.bumptech.glide.request.target.CustomViewTarget$SizeDeterminer.d(SourceFile:4)
        at com.bumptech.glide.request.target.CustomViewTarget.n(SourceFile:1)
        at com.bumptech.glide.request.SingleRequest.f(SourceFile:19)
        at com.bumptech.glide.manager.RequestTracker.g(SourceFile:3)
        at com.bumptech.glide.RequestManager.z(SourceFile:2)
        at com.bumptech.glide.RequestBuilder.v0(SourceFile:11)
        at com.bumptech.glide.RequestBuilder.w0(SourceFile:1)
        at com.bumptech.glide.RequestBuilder.u0(SourceFile:1)
        at <hidden>.ui.common.ImageLoader.e(SourceFile:3)
        at <hidden>.ui.common.ImageLoader.f(SourceFile:4)
        at <hidden>.ui.common.ImageLoader.g(SourceFile:1)
        at <hidden>.ui.common.ImageLoader.i(SourceFile:1)
        at <hidden>.ui.alias.manager.AliasManagerAdapter$AliasHolder.O(SourceFile:11)
        at <hidden>.ui.alias.manager.AliasManagerAdapter.w(SourceFile:1)
        at androidx.recyclerview.widget.RecyclerView$Adapter.x(SourceFile:1)
        at androidx.recyclerview.widget.RecyclerView$Adapter.c(SourceFile:8)
        at androidx.recyclerview.widget.RecyclerView$Recycler.H(SourceFile:7)
        at androidx.recyclerview.widget.RecyclerView$Recycler.I(SourceFile:55)
        at androidx.recyclerview.widget.RecyclerView$Recycler.p(SourceFile:1)
        at androidx.recyclerview.widget.RecyclerView$Recycler.o(SourceFile:1)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.d(SourceFile:3)
        at androidx.recyclerview.widget.LinearLayoutManager.p2(SourceFile:1)
        at androidx.recyclerview.widget.LinearLayoutManager.V1(SourceFile:9)
        at androidx.recyclerview.widget.LinearLayoutManager.Y0(SourceFile:65)
        at androidx.recyclerview.widget.RecyclerView.D(SourceFile:12)
        at androidx.recyclerview.widget.RecyclerView.B(SourceFile:15)
        at androidx.recyclerview.widget.RecyclerView.onLayout(SourceFile:2)
        at android.view.View.layout(View.java:16024)
        at android.view.ViewGroup.layout(ViewGroup.java:5243)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:639)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:574)
        at android.view.View.layout(View.java:16024)
        at android.view.ViewGroup.layout(ViewGroup.java:5243)
        at androidx.swiperefreshlayout.widget.SwipeRefreshLayout.onLayout(SourceFile:11)
        at android.view.View.layout(View.java:16024)
        at android.view.ViewGroup.layout(ViewGroup.java:5243)
        at androidx.constraintlayout.widget.ConstraintLayout.onLayout(SourceFile:12)
        at android.view.View.layout(View.java:16024)
        at android.view.ViewGroup.layout(ViewGroup.java:5243)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.G(SourceFile:18)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.M(SourceFile:7)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayout(SourceFile:8)
        at android.view.View.layout(View.java:16024)
        at android.view.ViewGroup.layout(ViewGroup.java:5243)
        at androidx.constraintlayout.widget.ConstraintLayout.onLayout(SourceFile:12)
        at android.view.View.layout(View.java:16024)
        at android.view.ViewGroup.layout(ViewGroup.java:5243)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:639)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:574)
        at android.view.View.layout(View.java:16024)
        at android.view.ViewGroup.layout(ViewGroup.java:5243)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1959)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1813)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1722)
        at android.view.View.layout(View.java:16024)
        at android.view.ViewGroup.layout(ViewGroup.java:5243)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:639)
        at android.widget.FrameLayout.onLayout(
02-04 04:51:12.493 8665-8665/com.privowny.stage.application E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.*.stage.application, PID: 8665
    java.lang.IllegalStateException: Cannot recycle a resource while it is still acquired
        at com.bumptech.glide.load.engine.EngineResource.recycle(EngineResource.java:68)
        at com.bumptech.glide.load.engine.ResourceRecycler$ResourceRecyclerCallback.handleMessage(ResourceRecycler.java:37)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:210)
        at android.app.ActivityThread.main(ActivityThread.java:5839)
        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:1113)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:879)
shenmaoqing commented 3 years ago

We found the reason why occur "Already released" Exception(when 2020-06-19). Here is the log:

06-19 20:17:29.860 21511 21511 I RequestTracker: resumeRequests(), start 06-19 20:17:29.865 21511 21511 I RequestTracker: clearRemoveAndMaybeRecycle(), request=com.bumptech.glide.request.SingleRequest@477f55a 06-19 20:17:29.866 21511 21511 D Request : recycle(), com.bumptech.glide.request.SingleRequest@477f55a 06-19 20:17:29.868 21511 21511 D Request : begin(), com.bumptech.glide.request.SingleRequest@477f55a

We can find it is happened in Main thread(single thread),but the execute order is : resumeRequests -> getSnapShot -> one of them run clearRemoveAndMaybeRecycle -> and then request.begin. Although we execute this in main thread, the request set is not thread safe.

Hope this can help