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 */ 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 */ 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 */ 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 */ 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 */ 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. 183 static void tearDown() { 184 glide = null; 185 } 186 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 */ 268 public BitmapPool getBitmapPool() { 269 return bitmapPool; 270 } 271 272 <Z, R> ResourceTranscoder<Z, R> buildTranscoder(Class<Z> decodedClass, Class<R> transcodedClass) { 273 return transcoderRegistry.get(decodedClass, transcodedClass); 274 } 275 276 <T, Z> DataLoadProvider<T, Z> buildDataProvider(Class<T> dataClass, Class<Z> decodedClass) { 277 return dataLoadProviderRegistry.get(dataClass, decodedClass); 278 } 279 280 <R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) { 281 return imageViewTargetFactory.buildTarget(imageView, transcodedClass); 282 } 283 284 Engine getEngine() { 285 return engine; 286 } 287 288 CenterCrop getBitmapCenterCrop() { 289 return bitmapCenterCrop; 290 } 291 292 FitCenter getBitmapFitCenter() { 293 return bitmapFitCenter; 294 } 295 296 GifBitmapWrapperTransformation getDrawableCenterCrop() { 297 return drawableCenterCrop; 298 } 299 300 GifBitmapWrapperTransformation getDrawableFitCenter() { 301 return drawableFitCenter; 302 } 303 304 Handler getMainHandler() { 305 return mainHandler; 306 } 307 308 DecodeFormat getDecodeFormat() { 309 return decodeFormat; 310 } 311 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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") 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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) 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 */ 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> { 640 public ClearTarget(View view) { 641 super(view); 642 } 643 644 @Override 645 public void onLoadStarted(Drawable placeholder) { 646 // Do nothing. 647 } 648 649 @Override 650 public void onLoadFailed(Exception e, Drawable errorDrawable) { 651 // Do nothing. 652 } 653 654 @Override 655 public void onResourceReady(Object resource, GlideAnimation<? super Object> glideAnimation) { 656 // Do nothing. 657 } 658 659 @Override 660 public void onLoadCleared(Drawable placeholder) { 661 // Do nothing. 662 } 663 } 664 } 665