Skip to content

Commit 73a8e01

Browse files
authored
Restart any non-running identical requests instead of ignoring them. (#2261)
Running requests are left to complete to avoid cancelling and restarting expensive operations (network or I/O). Completed requests are asked to begin again, but short cut the normal request pipeline and redeliver the previously loaded resource to ensure that Targets and RequestListeners are notified as expected. Failed, cancelled, paused etc requests (all other states) are simply restarted.
1 parent cea1cce commit 73a8e01

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

library/src/main/java/com/bumptech/glide/RequestBuilder.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,19 @@ public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
359359
Request request = buildRequest(target);
360360

361361
Request previous = target.getRequest();
362-
if (previous != null) {
363-
if (request.isEquivalentTo(previous)) {
364-
request.recycle();
365-
return target;
362+
if (request.isEquivalentTo(previous)) {
363+
request.recycle();
364+
// If the request is completed, beginning again will ensure the result is re-delivered,
365+
// triggering RequestListeners and Targets. If the request is failed, beginning again will
366+
// restart the request, giving it another chance to complete. If the request is already
367+
// running, we can let it continue running without interruption.
368+
if (!Preconditions.checkNotNull(previous).isRunning()) {
369+
previous.begin();
366370
}
367-
requestManager.clear(target);
371+
return target;
368372
}
369373

374+
requestManager.clear(target);
370375
target.setRequest(request);
371376
requestManager.track(target, request);
372377

library/src/main/java/com/bumptech/glide/request/SingleRequest.java

+18
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,24 @@ public void begin() {
217217
return;
218218
}
219219

220+
if (status == Status.RUNNING) {
221+
throw new IllegalArgumentException("Cannot restart a running request");
222+
}
223+
224+
// If we're restarted after we're complete (usually via something like a notifyDataSetChanged
225+
// that starts an identical request into the same Target or View), we can simply use the
226+
// resource and size we retrieved the last time around and skip obtaining a new size, starting a
227+
// new load etc. This does mean that users who want to restart a load because they expect that
228+
// the view size has changed will need to explicitly clear the View or Target before starting
229+
// the new load.
230+
if (status == Status.COMPLETE) {
231+
onResourceReady(resource, DataSource.MEMORY_CACHE);
232+
return;
233+
}
234+
235+
// Restarts for requests that are neither complete nor running can be treated as new requests
236+
// and can run again from the beginning.
237+
220238
status = Status.WAITING_FOR_SIZE;
221239
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
222240
onSizeReady(overrideWidth, overrideHeight);

0 commit comments

Comments
 (0)