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()); }