Skip to content

Commit 37127f0

Browse files
committedAug 30, 2018
Add global/activity/fragment scoped RequestListener API to Glide.
After this change, callers will be able to add one or more RequestListeners either to all requests started with Glide, or to all requests started within a particular Activity or Fragment. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=209947609
1 parent a9e1ae2 commit 37127f0

File tree

6 files changed

+124
-8
lines changed

6 files changed

+124
-8
lines changed
 

‎library/src/main/java/com/bumptech/glide/Glide.java

+14-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.view.View;
2323
import com.bumptech.glide.gifdecoder.GifDecoder;
2424
import com.bumptech.glide.load.DecodeFormat;
25+
import com.bumptech.glide.load.ImageHeaderParser;
2526
import com.bumptech.glide.load.ResourceDecoder;
2627
import com.bumptech.glide.load.data.InputStreamRewinder;
2728
import com.bumptech.glide.load.engine.Engine;
@@ -76,6 +77,7 @@
7677
import com.bumptech.glide.manager.ConnectivityMonitorFactory;
7778
import com.bumptech.glide.manager.RequestManagerRetriever;
7879
import com.bumptech.glide.module.ManifestParser;
80+
import com.bumptech.glide.request.RequestListener;
7981
import com.bumptech.glide.request.RequestOptions;
8082
import com.bumptech.glide.request.target.ImageViewTargetFactory;
8183
import com.bumptech.glide.request.target.Target;
@@ -319,7 +321,8 @@ private static void throwIncorrectGlideModule(Exception e) {
319321
@NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
320322
int logLevel,
321323
@NonNull RequestOptions defaultRequestOptions,
322-
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions) {
324+
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
325+
@NonNull List<RequestListener<Object>> defaultRequestListeners) {
323326
this.engine = engine;
324327
this.bitmapPool = bitmapPool;
325328
this.arrayPool = arrayPool;
@@ -342,10 +345,15 @@ private static void throwIncorrectGlideModule(Exception e) {
342345
}
343346
registry.register(new DefaultImageHeaderParser());
344347

345-
Downsampler downsampler = new Downsampler(registry.getImageHeaderParsers(),
346-
resources.getDisplayMetrics(), bitmapPool, arrayPool);
348+
List<ImageHeaderParser> imageHeaderParsers = registry.getImageHeaderParsers();
349+
Downsampler downsampler =
350+
new Downsampler(
351+
imageHeaderParsers,
352+
resources.getDisplayMetrics(),
353+
bitmapPool,
354+
arrayPool);
347355
ByteBufferGifDecoder byteBufferGifDecoder =
348-
new ByteBufferGifDecoder(context, registry.getImageHeaderParsers(), bitmapPool, arrayPool);
356+
new ByteBufferGifDecoder(context, imageHeaderParsers, bitmapPool, arrayPool);
349357
ResourceDecoder<ParcelFileDescriptor, Bitmap> parcelFileDescriptorVideoDecoder =
350358
VideoDecoder.parcel(bitmapPool);
351359
ByteBufferBitmapDecoder byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
@@ -409,7 +417,7 @@ Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder())
409417
Registry.BUCKET_GIF,
410418
InputStream.class,
411419
GifDrawable.class,
412-
new StreamGifDecoder(registry.getImageHeaderParsers(), byteBufferGifDecoder, arrayPool))
420+
new StreamGifDecoder(imageHeaderParsers, byteBufferGifDecoder, arrayPool))
413421
.append(Registry.BUCKET_GIF, ByteBuffer.class, GifDrawable.class, byteBufferGifDecoder)
414422
.append(GifDrawable.class, new GifDrawableEncoder())
415423
/* GIF Frames */
@@ -512,6 +520,7 @@ Uri.class, Bitmap.class, new ResourceBitmapDecoder(resourceDrawableDecoder, bitm
512520
imageViewTargetFactory,
513521
defaultRequestOptions,
514522
defaultTransitionOptions,
523+
defaultRequestListeners,
515524
engine,
516525
logLevel);
517526
}

‎library/src/main/java/com/bumptech/glide/GlideBuilder.java

+42-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import android.support.annotation.Nullable;
77
import android.support.v4.util.ArrayMap;
88
import android.util.Log;
9+
import com.bumptech.glide.load.DataSource;
910
import com.bumptech.glide.load.engine.Engine;
11+
import com.bumptech.glide.load.engine.GlideException;
1012
import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;
1113
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
1214
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPoolAdapter;
@@ -22,8 +24,12 @@
2224
import com.bumptech.glide.manager.DefaultConnectivityMonitorFactory;
2325
import com.bumptech.glide.manager.RequestManagerRetriever;
2426
import com.bumptech.glide.manager.RequestManagerRetriever.RequestManagerFactory;
27+
import com.bumptech.glide.request.RequestListener;
2528
import com.bumptech.glide.request.RequestOptions;
2629
import com.bumptech.glide.request.target.Target;
30+
import java.util.ArrayList;
31+
import java.util.Collections;
32+
import java.util.List;
2733
import java.util.Map;
2834

2935
/**
@@ -46,6 +52,8 @@ public final class GlideBuilder {
4652
private RequestManagerFactory requestManagerFactory;
4753
private GlideExecutor animationExecutor;
4854
private boolean isActiveResourceRetentionAllowed;
55+
@Nullable
56+
private List<RequestListener<Object>> defaultRequestListeners;
4957

5058
/**
5159
* Sets the {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} implementation to use
@@ -372,6 +380,32 @@ public GlideBuilder setIsActiveResourceRetentionAllowed(
372380
return this;
373381
}
374382

383+
/**
384+
* Adds a global {@link RequestListener} that will be added to every request started with Glide.
385+
*
386+
* <p>Multiple {@link RequestListener}s can be added here, in {@link RequestManager} scopes or
387+
* to individual {@link RequestBuilder}s. {@link RequestListener}s are called in the order they're
388+
* added. Even if an earlier {@link RequestListener} returns {@code true} from
389+
* {@link RequestListener#onLoadFailed(GlideException, Object, Target, boolean)} or
390+
* {@link RequestListener#onResourceReady(Object, Object, Target, DataSource, boolean)}, it will
391+
* not prevent subsequent {@link RequestListener}s from being called.
392+
*
393+
* <p>Because Glide requests can be started for any number of individual resource types, any
394+
* listener added here has to accept any generic resource type in
395+
* {@link RequestListener#onResourceReady(Object, Object, Target, DataSource, boolean)}. If you
396+
* must base the behavior of the listener on the resource type, you will need to use
397+
* {@code instanceof} to do so. It's not safe to cast resource types without first checking
398+
* with {@code instanceof}.
399+
*/
400+
@NonNull
401+
public GlideBuilder addGlobalRequestListener(@NonNull RequestListener<Object> listener) {
402+
if (defaultRequestListeners == null) {
403+
defaultRequestListeners = new ArrayList<>();
404+
}
405+
defaultRequestListeners.add(listener);
406+
return this;
407+
}
408+
375409
void setRequestManagerFactory(@Nullable RequestManagerFactory factory) {
376410
this.requestManagerFactory = factory;
377411
}
@@ -437,6 +471,12 @@ Glide build(@NonNull Context context) {
437471
isActiveResourceRetentionAllowed);
438472
}
439473

474+
if (defaultRequestListeners == null) {
475+
defaultRequestListeners = Collections.emptyList();
476+
} else {
477+
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
478+
}
479+
440480
RequestManagerRetriever requestManagerRetriever =
441481
new RequestManagerRetriever(requestManagerFactory);
442482

@@ -450,6 +490,7 @@ Glide build(@NonNull Context context) {
450490
connectivityMonitorFactory,
451491
logLevel,
452492
defaultRequestOptions.lock(),
453-
defaultTransitionOptions);
493+
defaultTransitionOptions,
494+
defaultRequestListeners);
454495
}
455496
}

‎library/src/main/java/com/bumptech/glide/GlideContext.java

+9
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
import android.widget.ImageView;
1010
import com.bumptech.glide.load.engine.Engine;
1111
import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;
12+
import com.bumptech.glide.request.RequestListener;
1213
import com.bumptech.glide.request.RequestOptions;
1314
import com.bumptech.glide.request.target.ImageViewTargetFactory;
1415
import com.bumptech.glide.request.target.ViewTarget;
16+
import java.util.List;
1517
import java.util.Map;
1618
import java.util.Map.Entry;
1719

@@ -28,6 +30,7 @@ public class GlideContext extends ContextWrapper {
2830
private final Registry registry;
2931
private final ImageViewTargetFactory imageViewTargetFactory;
3032
private final RequestOptions defaultRequestOptions;
33+
private final List<RequestListener<Object>> defaultRequestListeners;
3134
private final Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions;
3235
private final Engine engine;
3336
private final int logLevel;
@@ -39,20 +42,26 @@ public GlideContext(
3942
@NonNull ImageViewTargetFactory imageViewTargetFactory,
4043
@NonNull RequestOptions defaultRequestOptions,
4144
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
45+
@NonNull List<RequestListener<Object>> defaultRequestListeners,
4246
@NonNull Engine engine,
4347
int logLevel) {
4448
super(context.getApplicationContext());
4549
this.arrayPool = arrayPool;
4650
this.registry = registry;
4751
this.imageViewTargetFactory = imageViewTargetFactory;
4852
this.defaultRequestOptions = defaultRequestOptions;
53+
this.defaultRequestListeners = defaultRequestListeners;
4954
this.defaultTransitionOptions = defaultTransitionOptions;
5055
this.engine = engine;
5156
this.logLevel = logLevel;
5257

5358
mainHandler = new Handler(Looper.getMainLooper());
5459
}
5560

61+
public List<RequestListener<Object>> getDefaultRequestListeners() {
62+
return defaultRequestListeners;
63+
}
64+
5665
public RequestOptions getDefaultRequestOptions() {
5766
return defaultRequestOptions;
5867
}

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

+19-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static com.bumptech.glide.request.RequestOptions.signatureOf;
55
import static com.bumptech.glide.request.RequestOptions.skipMemoryCacheOf;
66

7+
import android.annotation.SuppressLint;
78
import android.content.Context;
89
import android.graphics.Bitmap;
910
import android.graphics.drawable.Drawable;
@@ -76,8 +77,12 @@ public class RequestBuilder<TranscodeType> implements Cloneable,
7677
private boolean isModelSet;
7778
private boolean isThumbnailBuilt;
7879

79-
protected RequestBuilder(Glide glide, RequestManager requestManager,
80-
Class<TranscodeType> transcodeClass, Context context) {
80+
@SuppressLint("CheckResult")
81+
protected RequestBuilder(
82+
@NonNull Glide glide,
83+
RequestManager requestManager,
84+
Class<TranscodeType> transcodeClass,
85+
Context context) {
8186
this.glide = glide;
8287
this.requestManager = requestManager;
8388
this.transcodeClass = transcodeClass;
@@ -86,6 +91,8 @@ protected RequestBuilder(Glide glide, RequestManager requestManager,
8691
this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
8792
this.requestOptions = defaultRequestOptions;
8893
this.glideContext = glide.getGlideContext();
94+
95+
initRequestListeners(requestManager.getDefaultRequestListeners());
8996
}
9097

9198
protected RequestBuilder(Class<TranscodeType> transcodeClass, RequestBuilder<?> other) {
@@ -95,6 +102,16 @@ protected RequestBuilder(Class<TranscodeType> transcodeClass, RequestBuilder<?>
95102
requestOptions = other.requestOptions;
96103
}
97104

105+
// Casting from Object to a specific type is always safe.
106+
@SuppressWarnings("unchecked")
107+
// addListener always returns the same instance.
108+
@SuppressLint("CheckResult")
109+
private void initRequestListeners(List<RequestListener<Object>> requestListeners) {
110+
for (RequestListener<Object> listener : requestListeners) {
111+
addListener((RequestListener<TranscodeType>) listener);
112+
}
113+
}
114+
98115
/**
99116
* Applies the given options to the request.
100117
*

‎library/src/main/java/com/bumptech/glide/RequestManager.java

+38
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
import android.support.annotation.Nullable;
1717
import android.support.annotation.RawRes;
1818
import android.view.View;
19+
import com.bumptech.glide.load.DataSource;
1920
import com.bumptech.glide.load.engine.DiskCacheStrategy;
21+
import com.bumptech.glide.load.engine.GlideException;
2022
import com.bumptech.glide.load.resource.gif.GifDrawable;
2123
import com.bumptech.glide.manager.ConnectivityMonitor;
2224
import com.bumptech.glide.manager.ConnectivityMonitorFactory;
@@ -26,6 +28,7 @@
2628
import com.bumptech.glide.manager.RequestTracker;
2729
import com.bumptech.glide.manager.TargetTracker;
2830
import com.bumptech.glide.request.Request;
31+
import com.bumptech.glide.request.RequestListener;
2932
import com.bumptech.glide.request.RequestOptions;
3033
import com.bumptech.glide.request.target.Target;
3134
import com.bumptech.glide.request.target.ViewTarget;
@@ -34,6 +37,8 @@
3437
import com.bumptech.glide.util.Util;
3538
import java.io.File;
3639
import java.net.URL;
40+
import java.util.List;
41+
import java.util.concurrent.CopyOnWriteArrayList;
3742

3843
/**
3944
* A class for managing and starting requests for Glide. Can use activity, fragment and connectivity
@@ -69,6 +74,10 @@ public void run() {
6974
};
7075
private final Handler mainHandler = new Handler(Looper.getMainLooper());
7176
private final ConnectivityMonitor connectivityMonitor;
77+
// Adding default listeners should be much less common than starting new requests. We want
78+
// some way of making sure that requests don't mutate our listeners without creating a new copy of
79+
// the list each time a request is started.
80+
private final CopyOnWriteArrayList<RequestListener<Object>> defaultRequestListeners;
7281

7382
private RequestOptions requestOptions;
7483

@@ -115,6 +124,8 @@ public RequestManager(
115124
}
116125
lifecycle.addListener(connectivityMonitor);
117126

127+
defaultRequestListeners =
128+
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
118129
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
119130

120131
glide.registerRequestManager(this);
@@ -174,6 +185,29 @@ public RequestManager setDefaultRequestOptions(@NonNull RequestOptions requestOp
174185
return this;
175186
}
176187

188+
/**
189+
* Adds a default {@link RequestListener} that will be added to every request started with this
190+
* {@link RequestManager}.
191+
*
192+
* <p>Multiple {@link RequestListener}s can be added here, in {@link RequestManager} scopes or
193+
* to individual {@link RequestBuilder}s. {@link RequestListener}s are called in the order they're
194+
* added. Even if an earlier {@link RequestListener} returns {@code true} from
195+
* {@link RequestListener#onLoadFailed(GlideException, Object, Target, boolean)} or
196+
* {@link RequestListener#onResourceReady(Object, Object, Target, DataSource, boolean)}, it will
197+
* not prevent subsequent {@link RequestListener}s from being called.
198+
*
199+
* <p>Because Glide requests can be started for any number of individual resource types, any
200+
* listener added here has to accept any generic resource type in
201+
* {@link RequestListener#onResourceReady(Object, Object, Target, DataSource, boolean)}. If you
202+
* must base the behavior of the listener on the resource type, you will need to use
203+
* {@code instanceof} to do so. It's not safe to cast resource types without first checking
204+
* with {@code instanceof}.
205+
*/
206+
public RequestManager addDefaultRequestListener(RequestListener<Object> requestListener) {
207+
defaultRequestListeners.add(requestListener);
208+
return this;
209+
}
210+
177211
/**
178212
* Returns true if loads for this {@link RequestManager} are currently paused.
179213
*
@@ -614,6 +648,10 @@ void track(@NonNull Target<?> target, @NonNull Request request) {
614648
requestTracker.runRequest(request);
615649
}
616650

651+
List<RequestListener<Object>> getDefaultRequestListeners() {
652+
return defaultRequestListeners;
653+
}
654+
617655
RequestOptions getDefaultRequestOptions() {
618656
return requestOptions;
619657
}

‎library/test/src/test/java/com/bumptech/glide/GlideContextTest.java

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.bumptech.glide.load.resource.gif.GifDrawable;
1515
import com.bumptech.glide.request.RequestOptions;
1616
import com.bumptech.glide.request.target.ImageViewTargetFactory;
17+
import java.util.Collections;
1718
import java.util.HashMap;
1819
import java.util.Map;
1920
import org.junit.Before;
@@ -41,6 +42,7 @@ public void setUp() {
4142
new ImageViewTargetFactory(),
4243
new RequestOptions(),
4344
transitionOptions,
45+
/*defaultRequestListeners=*/ Collections.emptyList(),
4446
mock(Engine.class),
4547
Log.DEBUG);
4648
}

0 commit comments

Comments
 (0)
Please sign in to comment.