diff --git a/library/src/main/java/com/bumptech/glide/load/engine/SourceGenerator.java b/library/src/main/java/com/bumptech/glide/load/engine/SourceGenerator.java
index d0aa0cff7b..59ec17004c 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/SourceGenerator.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/SourceGenerator.java
@@ -2,13 +2,16 @@
import android.util.Log;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.data.DataFetcher;
+import com.bumptech.glide.load.data.DataFetcher.DataCallback;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoader.LoadData;
import com.bumptech.glide.util.LogTime;
+import com.bumptech.glide.util.Synthetic;
import java.util.Collections;
/**
@@ -19,10 +22,7 @@
*
Depending on the disk cache strategy, source data may first be written to disk and then loaded
* from the cache file rather than returned directly.
*/
-class SourceGenerator
- implements DataFetcherGenerator,
- DataFetcher.DataCallback,
- DataFetcherGenerator.FetcherReadyCallback {
+class SourceGenerator implements DataFetcherGenerator, DataFetcherGenerator.FetcherReadyCallback {
private static final String TAG = "SourceGenerator";
private final DecodeHelper> helper;
@@ -60,12 +60,40 @@ public boolean startNext() {
&& (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
|| helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
started = true;
- loadData.fetcher.loadData(helper.getPriority(), this);
+ startNextLoad(loadData);
}
}
return started;
}
+ private void startNextLoad(final LoadData> toStart) {
+ loadData.fetcher.loadData(
+ helper.getPriority(),
+ new DataCallback() {
+ @Override
+ public void onDataReady(@Nullable Object data) {
+ if (isCurrentRequest(toStart)) {
+ onDataReadyInternal(toStart, data);
+ }
+ }
+
+ @Override
+ public void onLoadFailed(@NonNull Exception e) {
+ if (isCurrentRequest(toStart)) {
+ onLoadFailedInternal(toStart, e);
+ }
+ }
+ });
+ }
+
+ // We want reference equality explicitly to make sure we ignore results from old requests.
+ @SuppressWarnings({"PMD.CompareObjectsWithEquals", "WeakerAccess"})
+ @Synthetic
+ boolean isCurrentRequest(LoadData> requestLoadData) {
+ LoadData> currentLoadData = loadData;
+ return currentLoadData != null && currentLoadData == requestLoadData;
+ }
+
private boolean hasNextModelLoader() {
return loadDataListIndex < helper.getLoadData().size();
}
@@ -107,8 +135,9 @@ public void cancel() {
}
}
- @Override
- public void onDataReady(Object data) {
+ @SuppressWarnings("WeakerAccess")
+ @Synthetic
+ void onDataReadyInternal(LoadData> loadData, Object data) {
DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
dataToCache = data;
@@ -125,8 +154,9 @@ public void onDataReady(Object data) {
}
}
- @Override
- public void onLoadFailed(@NonNull Exception e) {
+ @SuppressWarnings("WeakerAccess")
+ @Synthetic
+ void onLoadFailedInternal(LoadData> loadData, @NonNull Exception e) {
cb.onDataFetcherFailed(originalKey, e, loadData.fetcher, loadData.fetcher.getDataSource());
}