Closed
Description
Glide Version: 3.7.0
Integration libraries: OkHttp3
Device/Android Version: All devices
Issue details / Repro steps / Use case background:
I have a fragment that contains a RecyclerView that loads Images using Glide. When the user scrolls really fast to the bottom and quits the app, the error occurs.
Glide load line / GlideModule
(if any) / list Adapter code (if any):
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof PostsViewHolder){
HomeFeedPosts.data postsData = postsList.get(position);
((PostsViewHolder) holder).title.setText(postsData.user.username);
Glide.with(((PostsViewHolder) holder).imagePost.getContext())
.load(postsData.images.standard_resolution.url)
.priority(Priority.IMMEDIATE)
.placeholder(R.drawable.grey_placeholder)
.into(((PostsViewHolder) holder).imagePost);
Glide.with(((PostsViewHolder) holder).imageAvatar.getContext())
.load(postsData.user.profile_picture)
.priority(Priority.LOW)
.into(((PostsViewHolder) holder).imageAvatar);
} else if (holder instanceof ProgressBarViewHolder){
((ProgressBarViewHolder) holder).progressBar.setIndeterminate(true);
}
}
Stack trace / LogCat:
java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:134)
at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:102)
at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:87)
at com.bumptech.glide.Glide.with(Glide.java:629)
at com.saphala.gokilpedia_mobile.adapters.HomeFeedAdapter.onBindViewHolder(HomeFeedAdapter.java:86)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5465)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5498)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4735)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4611)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1988)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1384)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1347)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1174)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1031)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4055)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:543)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5113)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
Activity
TWiStErRob commentedon Mar 27, 2016
Hmm, that's an interesting repro for this recurring issue. There's likely not a good way around it inside Glide, I suggest one of these workarounds (in descending order of quality):
Pass in a Glide object:
new HomeFeedAdapter(Glide.with(this))
This is a handy workaround, and it also makes your adapter flexible to use with fragment and activity as well; and the code cleaner:
view.getContext()
is usually a long way to access Glide.See http://stackoverflow.com/a/32887693/253468 why it's even an improvement.
list.setAdapter(null)
inonDestroy()
oronStop()
, which is incovenient to do all the timeCheck for
((Activity)view.getContext()).isDestroyed()
or similar method, which may be unsafe and is even more inconvenient to do all the timeUse
Glide.with(context.getApplicationContext())
, see http://stackoverflow.com/a/32887693/253468 why it may not be a good idea.TWiStErRob commentedon Mar 27, 2016
Curious: How do you "quit the app" quick enough that the items are binding too late?
rsaphala commentedon Mar 27, 2016
There's an OnScrollListener attached to the RecyclerView that loads more data from the server as you scroll to the bottom. To reproduce this issue simply scroll really fast and press the back button.
TWiStErRob commentedon Mar 27, 2016
Ah, I see, so your lazy loading delivers data to a dead activity, it's the same issue as the others: there was always a rogue async call involved.
rsaphala commentedon Mar 27, 2016
I might be wrong on this, but doesn't the first option create a memory leak?
TWiStErRob commentedon Mar 27, 2016
I think at worst there's a reference cycle, which doesn't prevent GC from doing its job.
RequestManager is aware of the activity/fragment lifecycle so any request will be cleared when they die, see linked SO. I don't think anything will be kept after destroy as the fragment is also destroyed.
rsaphala commentedon Mar 27, 2016
Ahh ok thanks for clearing that up! The issue is now fixed.
kuldiep commentedon Jul 20, 2016
hii...m stuck with java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed
i have three activities in my app..so when i am starting 2nd activity there are some images which are loaded by glide in AsyncTask then i m going to further activity...again i came back to 2nd activity("no error") then i come back to 1st activity now again when i am going to 2nd activity app crashes with that exception...i tried glide.clearMemory()..but it dosent work :( please help me out
TWiStErRob commentedon Jul 20, 2016
@kuldiep I can only say the usual: make sure you don't start a load when the activity is destroyed or being destroyed. You can cancel the async task when the activity ia finishing (e.g. onStop). Please open a new issue with some code and more details, if you want more help.
kuldiep commentedon Jul 20, 2016
thanks for help....i think i come up with another solution and it works..i m just clearing glide.get(this).clearMemory in onResume, onRestart nd onDestroy methods..as of now i am not getting any error :)
TWiStErRob commentedon Jul 20, 2016
@kuldiep You might as well just disable memory cache altogether (similar applies to bitmap pools): use
MemoryCacheAdapter
as seen in wiki; and remember, this is a not a solution you found, but a hack hiding the real problem.kuldiep commentedon Jul 20, 2016
ya my approach is not a solution but i'll keep your approach of stopping async task in onStop method for letter use..thanks
9 remaining items