• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.bumptech.glide;
2 
3 import android.annotation.TargetApi;
4 import android.app.Activity;
5 import android.content.Context;
6 import android.graphics.Bitmap;
7 import android.graphics.drawable.Drawable;
8 import android.net.Uri;
9 import android.os.Build;
10 import android.os.Handler;
11 import android.os.Looper;
12 import android.os.ParcelFileDescriptor;
13 import android.support.v4.app.Fragment;
14 import android.support.v4.app.FragmentActivity;
15 import android.util.Log;
16 import android.view.View;
17 import android.widget.ImageView;
18 
19 import com.bumptech.glide.load.DecodeFormat;
20 import com.bumptech.glide.load.engine.Engine;
21 import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
22 import com.bumptech.glide.load.engine.cache.MemoryCache;
23 import com.bumptech.glide.load.engine.prefill.BitmapPreFiller;
24 import com.bumptech.glide.load.engine.prefill.PreFillType;
25 import com.bumptech.glide.load.model.GenericLoaderFactory;
26 import com.bumptech.glide.load.model.GlideUrl;
27 import com.bumptech.glide.load.model.ImageVideoWrapper;
28 import com.bumptech.glide.load.model.ModelLoader;
29 import com.bumptech.glide.load.model.ModelLoaderFactory;
30 import com.bumptech.glide.load.model.file_descriptor.FileDescriptorFileLoader;
31 import com.bumptech.glide.load.model.file_descriptor.FileDescriptorResourceLoader;
32 import com.bumptech.glide.load.model.file_descriptor.FileDescriptorStringLoader;
33 import com.bumptech.glide.load.model.file_descriptor.FileDescriptorUriLoader;
34 import com.bumptech.glide.load.model.stream.HttpUrlGlideUrlLoader;
35 import com.bumptech.glide.load.model.stream.StreamByteArrayLoader;
36 import com.bumptech.glide.load.model.stream.StreamFileLoader;
37 import com.bumptech.glide.load.model.stream.StreamResourceLoader;
38 import com.bumptech.glide.load.model.stream.StreamStringLoader;
39 import com.bumptech.glide.load.model.stream.StreamUriLoader;
40 import com.bumptech.glide.load.model.stream.StreamUrlLoader;
41 import com.bumptech.glide.load.resource.bitmap.CenterCrop;
42 import com.bumptech.glide.load.resource.bitmap.FileDescriptorBitmapDataLoadProvider;
43 import com.bumptech.glide.load.resource.bitmap.FitCenter;
44 import com.bumptech.glide.load.resource.bitmap.GlideBitmapDrawable;
45 import com.bumptech.glide.load.resource.bitmap.ImageVideoDataLoadProvider;
46 import com.bumptech.glide.load.resource.bitmap.StreamBitmapDataLoadProvider;
47 import com.bumptech.glide.load.resource.drawable.GlideDrawable;
48 import com.bumptech.glide.load.resource.file.StreamFileDataLoadProvider;
49 import com.bumptech.glide.load.resource.gif.GifDrawable;
50 import com.bumptech.glide.load.resource.gif.GifDrawableLoadProvider;
51 import com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapper;
52 import com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperTransformation;
53 import com.bumptech.glide.load.resource.gifbitmap.ImageVideoGifDrawableLoadProvider;
54 import com.bumptech.glide.load.resource.transcode.GifBitmapWrapperDrawableTranscoder;
55 import com.bumptech.glide.load.resource.transcode.GlideBitmapDrawableTranscoder;
56 import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
57 import com.bumptech.glide.load.resource.transcode.TranscoderRegistry;
58 import com.bumptech.glide.manager.RequestManagerRetriever;
59 import com.bumptech.glide.provider.DataLoadProvider;
60 import com.bumptech.glide.provider.DataLoadProviderRegistry;
61 import com.bumptech.glide.request.FutureTarget;
62 import com.bumptech.glide.request.Request;
63 import com.bumptech.glide.request.animation.GlideAnimation;
64 import com.bumptech.glide.request.target.ImageViewTargetFactory;
65 import com.bumptech.glide.request.target.Target;
66 import com.bumptech.glide.request.target.ViewTarget;
67 import com.bumptech.glide.util.Util;
68 
69 import java.io.File;
70 import java.io.InputStream;
71 import java.net.URL;
72 
73 /**
74  * A singleton to present a simple static interface for building requests with {@link BitmapRequestBuilder} and
75  * maintaining an {@link Engine}, {@link BitmapPool}, {@link com.bumptech.glide.load.engine.cache.DiskCache} and
76  * {@link MemoryCache}.
77  */
78 public class Glide {
79     /** 250 MB of cache. */
80     static final int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;
81 
82     private static final String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
83     private static final String TAG = "Glide";
84     private static volatile Glide glide;
85 
86     private final GenericLoaderFactory loaderFactory;
87     private final Engine engine;
88     private final BitmapPool bitmapPool;
89     private final MemoryCache memoryCache;
90     private final DecodeFormat decodeFormat;
91     private final ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
92     private final TranscoderRegistry transcoderRegistry = new TranscoderRegistry();
93     private final DataLoadProviderRegistry dataLoadProviderRegistry;
94     private final CenterCrop bitmapCenterCrop;
95     private final GifBitmapWrapperTransformation drawableCenterCrop;
96     private final FitCenter bitmapFitCenter;
97     private final GifBitmapWrapperTransformation drawableFitCenter;
98     private final Handler mainHandler;
99     private final BitmapPreFiller bitmapPreFiller;
100 
101     /**
102      * Returns a directory with a default name in the private cache directory of the application to use to store
103      * retrieved media and thumbnails.
104      *
105      * @see #getPhotoCacheDir(android.content.Context, String)
106      *
107      * @param context A context.
108      */
getPhotoCacheDir(Context context)109     public static File getPhotoCacheDir(Context context) {
110         return getPhotoCacheDir(context, DEFAULT_DISK_CACHE_DIR);
111     }
112 
113     /**
114      * Returns a directory with the given name in the private cache directory of the application to use to store
115      * retrieved media and thumbnails.
116      *
117      * @see #getPhotoCacheDir(android.content.Context)
118      *
119      * @param context A context.
120      * @param cacheName The name of the subdirectory in which to store the cache.
121      */
getPhotoCacheDir(Context context, String cacheName)122     public static File getPhotoCacheDir(Context context, String cacheName) {
123         File cacheDir = context.getCacheDir();
124         if (cacheDir != null) {
125             File result = new File(cacheDir, cacheName);
126             if (!result.mkdirs() && (!result.exists() || !result.isDirectory())) {
127                 // File wasn't able to create a directory, or the result exists but not a directory
128                 return null;
129             }
130             return result;
131         }
132         if (Log.isLoggable(TAG, Log.ERROR)) {
133             Log.e(TAG, "default disk cache dir is null");
134         }
135         return null;
136     }
137 
138     /**
139      * Get the singleton.
140      *
141      * @return the singleton
142      */
get(Context context)143     public static Glide get(Context context) {
144         if (glide == null) {
145             synchronized (Glide.class) {
146                 if (glide == null) {
147                     glide = new GlideBuilder(context).createGlide();
148                 }
149             }
150         }
151 
152         return glide;
153     }
154 
155     /**
156      * Returns false if the {@link Glide} singleton has not yet been created and can therefore be setup using
157      * {@link #setup(GlideBuilder)}.
158      *
159      * @see #setup(GlideBuilder)
160      */
isSetup()161     public static boolean isSetup() {
162         return glide != null;
163     }
164 
165     /**
166      * Creates the {@link Glide} singleton using the given builder. Can be used to set options like cache sizes and
167      * locations.
168      *
169      * @see #isSetup()
170      *
171      * @param builder The builder.
172      * @throws IllegalArgumentException if the Glide singleton has already been created.
173      */
setup(GlideBuilder builder)174     public static void setup(GlideBuilder builder) {
175         if (isSetup()) {
176             throw new IllegalArgumentException("Glide is already setup, check with isSetup() first");
177         }
178 
179         glide = builder.createGlide();
180     }
181 
182     // For testing.
tearDown()183     static void tearDown() {
184         glide = null;
185     }
186 
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat)187     Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
188         this.engine = engine;
189         this.bitmapPool = bitmapPool;
190         this.memoryCache = memoryCache;
191         this.decodeFormat = decodeFormat;
192         loaderFactory = new GenericLoaderFactory(context);
193         mainHandler = new Handler(Looper.getMainLooper());
194         bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);
195 
196         dataLoadProviderRegistry = new DataLoadProviderRegistry();
197 
198         StreamBitmapDataLoadProvider streamBitmapLoadProvider =
199                 new StreamBitmapDataLoadProvider(bitmapPool, decodeFormat);
200         dataLoadProviderRegistry.register(InputStream.class, Bitmap.class, streamBitmapLoadProvider);
201 
202         FileDescriptorBitmapDataLoadProvider fileDescriptorLoadProvider =
203                 new FileDescriptorBitmapDataLoadProvider(bitmapPool, decodeFormat);
204         dataLoadProviderRegistry.register(ParcelFileDescriptor.class, Bitmap.class, fileDescriptorLoadProvider);
205 
206         ImageVideoDataLoadProvider imageVideoDataLoadProvider =
207                 new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);
208         dataLoadProviderRegistry.register(ImageVideoWrapper.class, Bitmap.class, imageVideoDataLoadProvider);
209 
210         GifDrawableLoadProvider gifDrawableLoadProvider =
211                 new GifDrawableLoadProvider(context, bitmapPool);
212         dataLoadProviderRegistry.register(InputStream.class, GifDrawable.class, gifDrawableLoadProvider);
213 
214         dataLoadProviderRegistry.register(ImageVideoWrapper.class, GifBitmapWrapper.class,
215                 new ImageVideoGifDrawableLoadProvider(imageVideoDataLoadProvider, gifDrawableLoadProvider, bitmapPool));
216 
217         dataLoadProviderRegistry.register(InputStream.class, File.class, new StreamFileDataLoadProvider());
218 
219         register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
220         register(File.class, InputStream.class, new StreamFileLoader.Factory());
221         register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
222         register(int.class, InputStream.class, new StreamResourceLoader.Factory());
223         register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
224         register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
225         register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
226         register(String.class, InputStream.class, new StreamStringLoader.Factory());
227         register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
228         register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
229         register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
230         register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
231         register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());
232 
233         transcoderRegistry.register(Bitmap.class, GlideBitmapDrawable.class,
234                 new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool));
235         transcoderRegistry.register(GifBitmapWrapper.class, GlideDrawable.class,
236                 new GifBitmapWrapperDrawableTranscoder(
237                         new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));
238 
239         bitmapCenterCrop = new CenterCrop(bitmapPool);
240         drawableCenterCrop = new GifBitmapWrapperTransformation(bitmapPool, bitmapCenterCrop);
241 
242         bitmapFitCenter = new FitCenter(bitmapPool);
243         drawableFitCenter = new GifBitmapWrapperTransformation(bitmapPool, bitmapFitCenter);
244     }
245 
246     /**
247      * Returns the {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} used to temporarily store
248      * {@link android.graphics.Bitmap}s so they can be reused to avoid garbage collections.
249      *
250      * <p>
251      *     Note - Using this pool directly can lead to undefined behavior and strange drawing errors. Any
252      *     {@link android.graphics.Bitmap} added to the pool must not be currently in use in any other part of the
253      *     application. Any {@link android.graphics.Bitmap} added to the pool must be removed from the pool before it
254      *     is added a second time.
255      * </p>
256      *
257      * <p>
258      *     Note - To make effective use of the pool, any {@link android.graphics.Bitmap} removed from the pool must
259      *     eventually be re-added. Otherwise the pool will eventually empty and will not serve any useful purpose.
260      * </p>
261      *
262      * <p>
263      *     The primary reason this object is exposed is for use in custom
264      *     {@link com.bumptech.glide.load.ResourceDecoder}s and {@link com.bumptech.glide.load.Transformation}s. Use
265      *     outside of these classes is not generally recommended.
266      * </p>
267      */
getBitmapPool()268     public BitmapPool getBitmapPool() {
269         return bitmapPool;
270     }
271 
buildTranscoder(Class<Z> decodedClass, Class<R> transcodedClass)272     <Z, R> ResourceTranscoder<Z, R> buildTranscoder(Class<Z> decodedClass, Class<R> transcodedClass) {
273         return transcoderRegistry.get(decodedClass, transcodedClass);
274     }
275 
buildDataProvider(Class<T> dataClass, Class<Z> decodedClass)276     <T, Z> DataLoadProvider<T, Z> buildDataProvider(Class<T> dataClass, Class<Z> decodedClass) {
277         return dataLoadProviderRegistry.get(dataClass, decodedClass);
278     }
279 
buildImageViewTarget(ImageView imageView, Class<R> transcodedClass)280     <R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
281         return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
282     }
283 
getEngine()284     Engine getEngine() {
285         return engine;
286     }
287 
getBitmapCenterCrop()288     CenterCrop getBitmapCenterCrop() {
289         return bitmapCenterCrop;
290     }
291 
getBitmapFitCenter()292     FitCenter getBitmapFitCenter() {
293         return bitmapFitCenter;
294     }
295 
getDrawableCenterCrop()296     GifBitmapWrapperTransformation getDrawableCenterCrop() {
297         return drawableCenterCrop;
298     }
299 
getDrawableFitCenter()300     GifBitmapWrapperTransformation getDrawableFitCenter() {
301         return drawableFitCenter;
302     }
303 
getMainHandler()304     Handler getMainHandler() {
305         return mainHandler;
306     }
307 
getDecodeFormat()308     DecodeFormat getDecodeFormat() {
309         return decodeFormat;
310     }
311 
getLoaderFactory()312     private GenericLoaderFactory getLoaderFactory() {
313         return loaderFactory;
314     }
315 
316     /**
317      * Pre-fills the {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} using the given sizes.
318      *
319      * <p>
320      *   Enough Bitmaps are added to completely fill the pool, so most or all of the Bitmaps currently in the pool will
321      *   be evicted. Bitmaps are allocated according to the weights of the given sizes, where each size gets
322      *   (weight / prefillWeightSum) percent of the pool to fill.
323      * </p>
324      *
325      * <p>
326      *     Note - Pre-filling is done asynchronously using and {@link android.os.MessageQueue.IdleHandler}. Any
327      *     currently running pre-fill will be cancelled and replaced by a call to this method.
328      * </p>
329      *
330      * <p>
331      *     This method should be used with caution, overly aggressive pre-filling is substantially worse than not
332      *     pre-filling at all. Pre-filling should only be started in onCreate to avoid constantly clearing and
333      *     re-filling the {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool}. Rotation should be carefully
334      *     considered as well. It may be worth calling this method only when no saved instance state exists so that
335      *     pre-filling only happens when the Activity is first created, rather than on every rotation.
336      * </p>
337      *
338      * @param bitmapAttributeBuilders The list of
339      *     {@link com.bumptech.glide.load.engine.prefill.PreFillType.Builder Builders} representing
340      *     individual sizes and configurations of {@link android.graphics.Bitmap}s to be pre-filled.
341      */
preFillBitmapPool(PreFillType.Builder... bitmapAttributeBuilders)342     public void preFillBitmapPool(PreFillType.Builder... bitmapAttributeBuilders) {
343         bitmapPreFiller.preFill(bitmapAttributeBuilders);
344     }
345 
346     /**
347      * Clears as much memory as possible.
348      *
349      * @see android.content.ComponentCallbacks2#onLowMemory()
350      */
clearMemory()351     public void clearMemory() {
352         bitmapPool.clearMemory();
353         memoryCache.clearMemory();
354     }
355 
356     /**
357      * Clears some memory with the exact amount depending on the given level.
358      *
359      * @see android.content.ComponentCallbacks2#onTrimMemory(int)
360      */
trimMemory(int level)361     public void trimMemory(int level) {
362         bitmapPool.trimMemory(level);
363         memoryCache.trimMemory(level);
364     }
365 
366     /**
367      * Adjusts Glide's current and maximum memory usage based on the given {@link MemoryCategory}.
368      *
369      * <p>
370      *     The default {@link MemoryCategory} is {@link MemoryCategory#NORMAL}. {@link MemoryCategory#HIGH} increases
371      *     Glide's maximum memory usage by up to 50% and {@link MemoryCategory#LOW} decreases Glide's maximum memory
372      *     usage by 50%. This method should be used to temporarily increase or decrease memory useage for a single
373      *     Activity or part of the app. Use {@link GlideBuilder#setMemoryCache(MemoryCache)} to set a permanent
374      *     memory size if you want to change the default.
375      * </p>
376      */
setMemoryCategory(MemoryCategory memoryCategory)377     public void setMemoryCategory(MemoryCategory memoryCategory) {
378         memoryCache.setSizeMultiplier(memoryCategory.getMultiplier());
379         bitmapPool.setSizeMultiplier(memoryCategory.getMultiplier());
380     }
381 
382     /**
383      * Cancel any pending loads Glide may have for the target and free any resources (such as {@link Bitmap}s) that may
384      * have been loaded for the target so they may be reused.
385      *
386      * @param target The Target to cancel loads for.
387      */
clear(Target<?> target)388     public static void clear(Target<?> target) {
389         Util.assertMainThread();
390         Request request = target.getRequest();
391         if (request != null) {
392             request.clear();
393         }
394     }
395 
396     /**
397      * Cancel any pending loads Glide may have for the target and free any resources that may have been loaded into
398      * the target so they may be reused.
399      *
400      * @param target The target to cancel loads for.
401      */
clear(FutureTarget<?> target)402     public static void clear(FutureTarget<?> target) {
403         target.clear();
404     }
405 
406     /**
407      * Cancel any pending loads Glide may have for the view and free any resources that may have been loaded for the
408      * view.
409      *
410      * <p>
411      *     Note that this will only work if {@link View#setTag(Object)} is not called on this view outside of Glide.
412      * </p>
413      *
414      * @see #clear(Target).
415      *
416      * @param view The view to cancel loads and free resources for.
417      * @throws IllegalArgumentException if an object other than Glide's metadata is set as the view's tag.
418      */
clear(View view)419     public static void clear(View view) {
420         Target<?> viewTarget = new ClearTarget(view);
421         clear(viewTarget);
422     }
423 
424     /**
425      * Use the given factory to build a {@link ModelLoader} for models of the given class. Generally the best use of
426      * this method is to replace one of the default factories or add an implementation for other similar low level
427      * models. Typically the {@link RequestManager#using(com.bumptech.glide.load.model.stream.StreamModelLoader)} or
428      * {@link RequestManager#using(com.bumptech.glide.load.model.file_descriptor.FileDescriptorModelLoader)} syntax is
429      * preferred because it directly links the model with the ModelLoader being used to load it. Any factory replaced
430      * by the given factory will have its {@link ModelLoaderFactory#teardown()}} method called.
431      *
432      * <p>
433      *     Note - If a factory already exists for the given class, it will be replaced. If that factory is not being
434      *     used for any other model class, {@link ModelLoaderFactory#teardown()}
435      *     will be called.
436      * </p>
437      *
438      * <p>
439      *     Note - The factory must not be an anonymous inner class of an Activity or another object that cannot be
440      *     retained statically.
441      * </p>
442      *
443      * @see RequestManager#using(com.bumptech.glide.load.model.file_descriptor.FileDescriptorModelLoader)
444      * @see RequestManager#using(com.bumptech.glide.load.model.stream.StreamModelLoader)
445      *
446      * @param modelClass The model class.
447      * @param resourceClass The resource class the model loader will translate the model type into.
448      * @param factory The factory to use.
449      * @param <T> The type of the model.
450      * @param <Y> the type of the resource.
451      */
register(Class<T> modelClass, Class<Y> resourceClass, ModelLoaderFactory<T, Y> factory)452     public <T, Y> void register(Class<T> modelClass, Class<Y> resourceClass, ModelLoaderFactory<T, Y> factory) {
453         ModelLoaderFactory<T, Y> removed = loaderFactory.register(modelClass, resourceClass, factory);
454         if (removed != null) {
455             removed.teardown();
456         }
457     }
458 
459     /**
460      * Removes any {@link ModelLoaderFactory} registered for the given model and resource classes if one exists. If a
461      * {@link ModelLoaderFactory} is removed, its {@link ModelLoaderFactory#teardown()}} method will be called.
462      *
463      * @param modelClass The model class.
464      * @param resourceClass The resource class.
465      * @param <T> The type of the model.
466      * @param <Y> The type of the resource.
467      */
unregister(Class<T> modelClass, Class<Y> resourceClass)468     public <T, Y> void unregister(Class<T> modelClass, Class<Y> resourceClass) {
469         ModelLoaderFactory<T, Y> removed = loaderFactory.unregister(modelClass, resourceClass);
470         if (removed != null) {
471             removed.teardown();
472         }
473     }
474 
475     /**
476      * Build a {@link ModelLoader} for the given model class using registered {@link ModelLoaderFactory}s.
477      *
478      * @see  #buildModelLoader(Object, Class, Context)
479      * @see  #buildStreamModelLoader(Class, Context)
480      * @see  #buildFileDescriptorModelLoader(Class, Context)
481      *
482      * @param modelClass The class to get a {@link ModelLoader} for.
483      * @param resourceClass The resource class to get a {@link ModelLoader} for.
484      * @param context Any context.
485      * @param <T> The type of the model.
486      * @param <Y> The type of the resource.
487      * @return A new {@link ModelLoader} for the given model class.
488      */
buildModelLoader(Class<T> modelClass, Class<Y> resourceClass, Context context)489     public static <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass,
490             Context context) {
491          if (modelClass == null) {
492             if (Log.isLoggable(TAG, Log.DEBUG)) {
493                 Log.d(TAG, "Unable to load null model, setting placeholder only");
494             }
495             return null;
496         }
497         return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
498     }
499 
500     /**
501      * A convenience method to build a {@link ModelLoader} for a given model object using registered
502      * {@link ModelLoaderFactory}s.
503      *
504      * @see #buildModelLoader(Class, Class, Context)
505      *
506      * @param model A non null model object whose class we will get a {@link ModelLoader} for.
507      * @param resourceClass The resource class to get a {@link ModelLoader} for.
508      * @param context Any context.
509      * @param <T> The type of the model.
510      * @param <Y> The type of the resource.
511      * @return A new {@link ModelLoader} for the given model and resource classes, or null if model is null.
512      */
513     @SuppressWarnings("unchecked")
buildModelLoader(T model, Class<Y> resourceClass, Context context)514     public static <T, Y> ModelLoader<T, Y> buildModelLoader(T model, Class<Y> resourceClass, Context context) {
515         return buildModelLoader(model != null ? (Class<T>) model.getClass() : null, resourceClass, context);
516     }
517 
518     /**
519      * A method to build a {@link ModelLoader} for the given model that produces {@link InputStream}s using a registered
520      * factory.
521      *
522      * @see #buildModelLoader(Class, Class, android.content.Context)
523      */
buildStreamModelLoader(Class<T> modelClass, Context context)524     public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(Class<T> modelClass, Context context) {
525         return buildModelLoader(modelClass, InputStream.class, context);
526     }
527 
528     /**
529      * A method to build a {@link ModelLoader} for the given model that produces {@link InputStream}s using a registered
530      * factory.
531      *
532      * @see #buildModelLoader(Object, Class, Context)
533      */
buildStreamModelLoader(T model, Context context)534     public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(T model, Context context) {
535         return buildModelLoader(model, InputStream.class, context);
536     }
537 
538     /**
539      * A method to build a {@link ModelLoader} for the given model class that produces
540      * {@link ParcelFileDescriptor}s using a registered factory.
541      *
542      * @see #buildModelLoader(Class, Class, android.content.Context)
543      */
buildFileDescriptorModelLoader(Class<T> modelClass, Context context)544     public static <T> ModelLoader<T, ParcelFileDescriptor> buildFileDescriptorModelLoader(Class<T> modelClass,
545             Context context) {
546         return buildModelLoader(modelClass, ParcelFileDescriptor.class, context);
547     }
548 
549     /**
550      * A method to build a {@link ModelLoader} for the given model class that produces
551      * {@link ParcelFileDescriptor}s using a registered factory.
552      *
553      * @see #buildModelLoader(Object, Class, android.content.Context)
554      */
buildFileDescriptorModelLoader(T model, Context context)555     public static <T> ModelLoader<T, ParcelFileDescriptor> buildFileDescriptorModelLoader(T model, Context context) {
556         return buildModelLoader(model, ParcelFileDescriptor.class, context);
557     }
558 
559     /**
560      * Begin a load with Glide by passing in a context.
561      *
562      * <p>
563      *     Any requests started using a context will only have the application level options applied and will not be
564      *     started or stopped based on lifecycle events. In general, loads should be started at the level the result
565      *     will be used in. If the resource will be used in a view in a child fragment,
566      *     the load should be started with {@link #with(android.app.Fragment)}} using that child fragment. Similarly,
567      *     if the resource will be used in a view in the parent fragment, the load should be started with
568      *     {@link #with(android.app.Fragment)} using the parent fragment. In the same vein, if the resource will be used
569      *     in a view in an activity, the load should be started with {@link #with(android.app.Activity)}}.
570      * </p>
571      *
572      * <p>
573      *     This method is appropriate for resources that will be used outside of the normal fragment or activity
574      *     lifecycle (For example in services, or for notification thumbnails).
575      * </p>
576      *
577      * @see #with(android.app.Activity)
578      * @see #with(android.app.Fragment)
579      * @see #with(android.support.v4.app.Fragment)
580      * @see #with(android.support.v4.app.FragmentActivity)
581      *
582      * @param context Any context, will not be retained.
583      * @return A RequestManager for the top level application that can be used to start a load.
584      */
with(Context context)585     public static RequestManager with(Context context) {
586         RequestManagerRetriever retriever = RequestManagerRetriever.get();
587         return retriever.get(context);
588     }
589 
590     /**
591      * Begin a load with Glide that will be tied to the given {@link android.app.Activity}'s lifecycle and that uses the
592      * given {@link Activity}'s default options.
593      *
594      * @param activity The activity to use.
595      * @return A RequestManager for the given activity that can be used to start a load.
596      */
with(Activity activity)597     public static RequestManager with(Activity activity) {
598         RequestManagerRetriever retriever = RequestManagerRetriever.get();
599         return retriever.get(activity);
600     }
601 
602     /**
603      * Begin a load with Glide that will tied to the give {@link android.support.v4.app.FragmentActivity}'s lifecycle
604      * and that uses the given {@link android.support.v4.app.FragmentActivity}'s default options.
605      *
606      * @param activity The activity to use.
607      * @return A RequestManager for the given FragmentActivity that can be used to start a load.
608      */
with(FragmentActivity activity)609     public static RequestManager with(FragmentActivity activity) {
610         RequestManagerRetriever retriever = RequestManagerRetriever.get();
611         return retriever.get(activity);
612     }
613 
614     /**
615      * Begin a load with Glide that will be tied to the given {@link android.app.Fragment}'s lifecycle and that uses
616      * the given {@link android.app.Fragment}'s default options.
617      *
618      * @param fragment The fragment to use.
619      * @return A RequestManager for the given Fragment that can be used to start a load.
620      */
621     @TargetApi(Build.VERSION_CODES.HONEYCOMB)
with(android.app.Fragment fragment)622     public static RequestManager with(android.app.Fragment fragment) {
623         RequestManagerRetriever retriever = RequestManagerRetriever.get();
624         return retriever.get(fragment);
625     }
626 
627     /**
628      * Begin a load with Glide that will be tied to the given {@link android.support.v4.app.Fragment}'s lifecycle and
629      * that uses the given {@link android.support.v4.app.Fragment}'s default options.
630      *
631      * @param fragment The fragment to use.
632      * @return A RequestManager for the given Fragment that can be used to start a load.
633      */
with(Fragment fragment)634     public static RequestManager with(Fragment fragment) {
635         RequestManagerRetriever retriever = RequestManagerRetriever.get();
636         return retriever.get(fragment);
637     }
638 
639     private static class ClearTarget extends ViewTarget<View, Object> {
ClearTarget(View view)640         public ClearTarget(View view) {
641             super(view);
642         }
643 
644         @Override
onLoadStarted(Drawable placeholder)645         public void onLoadStarted(Drawable placeholder) {
646             // Do nothing.
647         }
648 
649         @Override
onLoadFailed(Exception e, Drawable errorDrawable)650         public void onLoadFailed(Exception e, Drawable errorDrawable) {
651             // Do nothing.
652         }
653 
654         @Override
onResourceReady(Object resource, GlideAnimation<? super Object> glideAnimation)655         public void onResourceReady(Object resource, GlideAnimation<? super Object> glideAnimation) {
656             // Do nothing.
657         }
658 
659         @Override
onLoadCleared(Drawable placeholder)660         public void onLoadCleared(Drawable placeholder) {
661             // Do nothing.
662         }
663     }
664 }
665