package com.bumptech.glide; import android.annotation.TargetApi; import android.app.Activity; import android.content.ComponentCallbacks2; import android.content.Context; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.util.Log; import android.view.View; import android.widget.ImageView; import com.android.volley.RequestQueue; import com.bumptech.glide.load.engine.Engine; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.load.engine.cache.DiskCache; import com.bumptech.glide.load.engine.cache.MemoryCache; import com.bumptech.glide.load.model.GenericLoaderFactory; import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.load.model.ImageVideoWrapper; import com.bumptech.glide.load.model.ModelLoader; import com.bumptech.glide.load.model.ModelLoaderFactory; import com.bumptech.glide.load.model.file_descriptor.FileDescriptorFileLoader; import com.bumptech.glide.load.model.file_descriptor.FileDescriptorModelLoader; import com.bumptech.glide.load.model.file_descriptor.FileDescriptorResourceLoader; import com.bumptech.glide.load.model.file_descriptor.FileDescriptorStringLoader; import com.bumptech.glide.load.model.file_descriptor.FileDescriptorUriLoader; import com.bumptech.glide.load.model.stream.StreamFileLoader; import com.bumptech.glide.load.model.stream.StreamModelLoader; import com.bumptech.glide.load.model.stream.StreamResourceLoader; import com.bumptech.glide.load.model.stream.StreamStringLoader; import com.bumptech.glide.load.model.stream.StreamUriLoader; import com.bumptech.glide.load.model.stream.StreamUrlLoader; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.FileDescriptorBitmapDataLoadProvider; import com.bumptech.glide.load.resource.bitmap.FitCenter; import com.bumptech.glide.load.resource.bitmap.ImageVideoDataLoadProvider; import com.bumptech.glide.load.resource.bitmap.StreamBitmapDataLoadProvider; import com.bumptech.glide.load.resource.gif.GifData; import com.bumptech.glide.load.resource.gif.GifDataLoadProvider; import com.bumptech.glide.load.resource.gif.GifDrawable; import com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapper; import com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperTransformation; import com.bumptech.glide.load.resource.gifbitmap.ImageVideoGifDataLoadProvider; import com.bumptech.glide.load.resource.transcode.BitmapDrawableTranscoder; import com.bumptech.glide.load.resource.transcode.GifBitmapWrapperDrawableTranscoder; import com.bumptech.glide.load.resource.transcode.GifDataDrawableTranscoder; import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; import com.bumptech.glide.load.resource.transcode.TranscoderFactory; import com.bumptech.glide.manager.RequestManagerRetriever; import com.bumptech.glide.provider.DataLoadProviderFactory; import com.bumptech.glide.request.GlideAnimation; import com.bumptech.glide.request.Request; import com.bumptech.glide.request.target.ImageViewTargetFactory; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.ViewTarget; import com.bumptech.glide.volley.VolleyUrlLoader; import java.io.File; import java.io.InputStream; import java.net.URL; /** * A singleton to present a simple static interface for building requests with {@link BitmapRequestBuilder} and maintaining * an {@link Engine}, {@link BitmapPool}, {@link DiskCache} and {@link MemoryCache}. * *
* Note - This class is not thread safe. *
*/ public class Glide { // 250 MB static final int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024; private static final String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache"; private static final String TAG = "Glide"; private static Glide GLIDE; private final GenericLoaderFactory loaderFactory = new GenericLoaderFactory(); private final RequestQueue requestQueue; private final Engine engine; private final BitmapPool bitmapPool; private final MemoryCache memoryCache; private final ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory(); private final TranscoderFactory transcoderFactory = new TranscoderFactory(); private final DataLoadProviderFactory dataLoadProviderFactory; private final CenterCrop bitmapCenterCrop; private final GifBitmapWrapperTransformation drawableCenterCrop; private final FitCenter bitmapFitCenter; private final GifBitmapWrapperTransformation drawableFitCenter; /** * Try to get the external cache directory if available and default to the internal. Use a default name for the * cache directory if no name is provided * * @param context A context * @return A File representing the default disk cache directory */ public static File getPhotoCacheDir(Context context) { return getPhotoCacheDir(context, DEFAULT_DISK_CACHE_DIR); } /** * Try to get the external cache directory if available and default to the internal. Use a default name for the * cache directory if no name is provided * * @param context A context * @param cacheName The name of the subdirectory in which to store the cache * @return A File representing the default disk cache directory */ @SuppressWarnings("ResultOfMethodCallIgnored") public static File getPhotoCacheDir(Context context, String cacheName) { File cacheDir = context.getCacheDir(); if (cacheDir != null) { File result = new File(cacheDir, cacheName); result.mkdirs(); return result; } if (Log.isLoggable(TAG, Log.ERROR)) { Log.e(TAG, "default disk cache dir is null"); } return null; } /** * Get the singleton. * * @return the singleton */ public static Glide get(Context context) { if (GLIDE == null) { GLIDE = new GlideBuilder(context).createGlide(); } return GLIDE; } /** * Returns false if the {@link Glide} singleton has not yet been created and can therefore be setup using * {@link #setup(GlideBuilder)}. * * @see #setup(GlideBuilder) */ public static boolean isSetup() { return GLIDE != null; } /** * Creates the {@link Glide} singleton using the given builder. Can be used to set options like cache sizes and * locations. * * @see #isSetup() * * @param builder The builder. * @throws IllegalArgumentException if the Glide singleton has already been created. */ public static void setup(GlideBuilder builder) { if (isSetup()) { throw new IllegalArgumentException("Glide is already setup, check with isSetup() first"); } GLIDE = builder.createGlide(); } static void tearDown() { GLIDE = null; } Glide(Engine engine, RequestQueue requestQueue, MemoryCache memoryCache, BitmapPool bitmapPool, Context context) { this.engine = engine; this.requestQueue = requestQueue; this.bitmapPool = bitmapPool; this.memoryCache = memoryCache; dataLoadProviderFactory = new DataLoadProviderFactory(); dataLoadProviderFactory.register(InputStream.class, Bitmap.class, new StreamBitmapDataLoadProvider(bitmapPool)); dataLoadProviderFactory.register(ParcelFileDescriptor.class, Bitmap.class, new FileDescriptorBitmapDataLoadProvider(bitmapPool)); ImageVideoDataLoadProvider imageVideoDataLoadProvider = new ImageVideoDataLoadProvider(bitmapPool); dataLoadProviderFactory.register(ImageVideoWrapper.class, Bitmap.class, imageVideoDataLoadProvider); GifDataLoadProvider gifDataLoadProvider = new GifDataLoadProvider(context, bitmapPool); dataLoadProviderFactory.register(InputStream.class, GifData.class, gifDataLoadProvider); dataLoadProviderFactory.register(ImageVideoWrapper.class, GifBitmapWrapper.class, new ImageVideoGifDataLoadProvider(imageVideoDataLoadProvider, gifDataLoadProvider)); register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory()); register(File.class, InputStream.class, new StreamFileLoader.Factory()); register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory()); register(Integer.class, InputStream.class, new StreamResourceLoader.Factory()); register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory()); register(String.class, InputStream.class, new StreamStringLoader.Factory()); register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory()); register(Uri.class, InputStream.class, new StreamUriLoader.Factory()); register(URL.class, InputStream.class, new StreamUrlLoader.Factory()); register(GlideUrl.class, InputStream.class, new VolleyUrlLoader.Factory(requestQueue)); transcoderFactory.register(Bitmap.class, BitmapDrawable.class, new BitmapDrawableTranscoder(context.getResources(), bitmapPool)); transcoderFactory.register(GifBitmapWrapper.class, Drawable.class, new GifBitmapWrapperDrawableTranscoder(new BitmapDrawableTranscoder(context.getResources(), bitmapPool), new GifDataDrawableTranscoder())); transcoderFactory.register(GifData.class, GifDrawable.class, new GifDataDrawableTranscoder()); bitmapCenterCrop = new CenterCrop(bitmapPool); drawableCenterCrop = new GifBitmapWrapperTransformation(bitmapCenterCrop); bitmapFitCenter = new FitCenter(bitmapPool); drawableFitCenter = new GifBitmapWrapperTransformation(bitmapFitCenter); } public BitmapPool getBitmapPool() { return bitmapPool; }* The default {@link MemoryCategory} is {@link MemoryCategory#NORMAL}. {@link MemoryCategory#HIGH} increases * Glide's maximum memory usage by up to 50% and {@link MemoryCategory#LOW} decreases Glide's maximum memory * usage by 50%. This method should be used to temporarily increase or decrease memory useage for a single * Activity or part of the app. Use {@link GlideBuilder#setMemoryCache(MemoryCache)} to set a permanent * memory size if you want to change the default. *
*/ public void setMemoryCategory(MemoryCategory memoryCategory) { memoryCache.setSizeMultiplier(memoryCategory.getMultiplier()); bitmapPool.setSizeMultiplier(memoryCategory.getMultiplier()); } /** * Cancel any pending loads Glide may have for the target and free any resources (such as {@link Bitmap}s) that may * have been loaded for the target so they may be reused. * * @param target The Target to cancel loads for. */ public static void clear(Target target) { Request request = target.getRequest(); if (request!= null) { request.clear(); } } /** * Cancel any pending loads Glide may have for the view and free any resources that may have been loaded for the * view. * ** Note that this will only work if {@link View#setTag(Object)} is not called on this view outside of Glide. *
* * @see #clear(Target). * * @param view The view to cancel loads and free resources for. * @throws IllegalArgumentException if an object other than Glide's metadata is set as the view's tag. */ public static void clear(View view) { Target viewTarget = new ClearTarget(view); clear(viewTarget); } /** * Use the given factory to build a {@link ModelLoader} for models of the given class. Generally the best use of * this method is to replace one of the default factories or add an implementation for other similar low level * models. Typically the {@link RequestManager#using(StreamModelLoader)} or * {@link RequestManager#using(FileDescriptorModelLoader)} syntax is preferred because it directly links the model * with the ModelLoader being used to load it. Any factory replaced by the given factory will have its * {@link ModelLoaderFactory#teardown()}} method called. * ** Note - If a factory already exists for the given class, it will be replaced. If that factory is not being * used for any other model class, {@link ModelLoaderFactory#teardown()} * will be called. *
* ** Note - The factory must not be an anonymous inner class of an Activity or another object that cannot be * retained statically. *
* * @see RequestManager#using(FileDescriptorModelLoader) * @see RequestManager#using(StreamModelLoader) * * @param modelClass The model class. * @param resourceClass The resource class the model loader will translate the model type into. * @param factory The factory to use. * @param