Skip to content

Commit

Permalink
Restart any non-running identical requests instead of ignoring them. (#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
sjudd authored Aug 18, 2017
1 parent cea1cce commit 73a8e01
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
15 changes: 10 additions & 5 deletions library/src/main/java/com/bumptech/glide/RequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -359,14 +359,19 @@ public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
Request request = buildRequest(target);

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

requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,24 @@ public void begin() {
return;
}

if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}

// If we're restarted after we're complete (usually via something like a notifyDataSetChanged
// that starts an identical request into the same Target or View), we can simply use the
// resource and size we retrieved the last time around and skip obtaining a new size, starting a
// new load etc. This does mean that users who want to restart a load because they expect that
// the view size has changed will need to explicitly clear the View or Target before starting
// the new load.
if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}

// Restarts for requests that are neither complete nor running can be treated as new requests
// and can run again from the beginning.

status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
Expand Down

0 comments on commit 73a8e01

Please sign in to comment.