In Picasso we have a tag(Object tag) method, that give us an ability to cancel all 'tagged' requests simply by calling Picasso.cancel(Object tag).
In my application i use Glide (and want to use it), and in some cases i need to create Glide instance using application context:
Glide.with(context.getApplicationContext())
So, this occurs in different places in my app (more specifically, when drawing items of different recycle views) and i want to cancel all image load requests that are related to one or other recycle view at the moment, when user leaves corresponding UI scene.
I deliberately avoided words "Activity" or "Fragment", using "Scene" instead, because these recycle views are drawn using WindowManager (like a facebook messenger's chatheads) and there no any Activityor Fragmentat all.
So, what the recommended way to cancel some logical group of requests in a batch manner?
Thank you, and sorry for my poor english.
The simplest form of cancellation is keeping a reference to whatever is returned from .into() (or list of those) and Glide.clear()-ing it when you want to.
Since you have a RecyclerView, I suggest the following solution:
onViewRecycled and call Glide.clear(holder.imageView)rv.setAdapter(null)Glide.clear calls and you don't need to hold onto the Targets yourself (which can be tricky considering recycling).Alternatively you can try to create and maintain RequestManagers for your scenes, but I would consider that extremely advanced usage. If anything goes wrong there, you're on your own.
Note to future readers: DO NOT use this solution if you have access to fragments. Using the correct "context" gives you safety mechanisms that are worth the trouble of passing in a RequestManager into the adapter, see http://stackoverflow.com/a/32887693/253468 for more info.
That can be used as satisfiable solution (guava library required):
private class Targets {
private final Map<View, Target> views = new MapMaker().weakKeys().weakValues().makeMap();
private final Map<Target, Object> targets = new MapMaker().weakKeys().makeMap();
private boolean terminated;
public void add(View view, Target target) {
if (terminated) {
return;
}
final Target previous = views.put(view, target);
if (previous != null) {
targets.remove(previous);
}
targets.put(target, Targets.class);
}
public void cancelAll() {
terminated = true;
views.clear();
for (Target target : targets.keySet()) {
if (target != null) {
Glide.clear(target);
}
}
targets.clear();
}
}
Usage example:
private final Targets targets = new Targets();
private void loadImage() {
final Target target = request.into(imageView);
targets.add(imageView, target);
}
private void cancelAll() {
targets.cancelAll();
}
Most helpful comment
The simplest form of cancellation is keeping a reference to whatever is returned from
.into()(or list of those) andGlide.clear()-ing it when you want to.Since you have a
RecyclerView, I suggest the following solution:onViewRecycledand callGlide.clear(holder.imageView)rv.setAdapter(null)This will trigger a series of
Glide.clearcalls and you don't need to hold onto the Targets yourself (which can be tricky considering recycling).Alternatively you can try to create and maintain RequestManagers for your scenes, but I would consider that extremely advanced usage. If anything goes wrong there, you're on your own.
Note to future readers: DO NOT use this solution if you have access to fragments. Using the correct "context" gives you safety mechanisms that are worth the trouble of passing in a
RequestManagerinto the adapter, see http://stackoverflow.com/a/32887693/253468 for more info.