上一篇文章从源码角度深刻理解Glide(上)中,咱们已经把Glide加载图片的基本流程走了一遍,想必你已经对Glide的加载原理有了新的认识而且见识到了Glide源码的复杂逻辑,在咱们感叹Glide源码复杂的同时咱们也忽略了Glide加载图片过程的其它细节,特别是缓存方面,咱们在上一篇文章中对于缓存的处理都是跳过的,这一篇文章咱们就从Glide的缓存开始再次对Glide进行深刻理解。html
Glide加载默认状况下能够分为三级缓存,哪三级呢?他们分别是内存、磁盘和网络。git
默认状况下,Glide 会在开始一个新的图片请求以前检查如下多级的缓存:github
网络级别的加载咱们已经在上一篇文章了解了,上面列出的前两种状况则是内存缓存,后两种状况则是磁盘缓存,若是以上四种状况都不存在,Glide则会经过返回到原始资源以取回数据(原始文件,Uri, Url(网络)等)算法
/**Key 接口*/ public interface Key { String STRING_CHARSET_NAME = "UTF-8"; Charset CHARSET = Charset.forName(STRING_CHARSET_NAME); void updateDiskCacheKey(@NonNull MessageDigest messageDigest); @Override boolean equals(Object o); @Override int hashCode(); } 复制代码
private final EngineKeyFactory keyFactory; /**Engine类的load方法*/ public <R> LoadStatus load(GlideContext glideContext,Object model, Key signature,int width,int height,Class<?> resourceClass,Class<R> transcodeClass,Priority priority,DiskCacheStrategy diskCacheStrategy,Map<Class<?>, Transformation<?>> transformations,boolean isTransformationRequired,boolean isScaleOnlyOrNoTransform, Options options,boolean isMemoryCacheable,boolean useUnlimitedSourceExecutorPool,boolean useAnimationPool,boolean onlyRetrieveFromCache,ResourceCallback cb) { Util.assertMainThread(); long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0; EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations, resourceClass, transcodeClass, options); //省略部分代码 .......... } /**EngineKey类*/ class EngineKey implements Key { private final Object model; private final int width; private final int height; private final Class<?> resourceClass; private final Class<?> transcodeClass; private final Key signature; private final Map<Class<?>, Transformation<?>> transformations; private final Options options; private int hashCode; EngineKey( Object model, Key signature, int width, int height, Map<Class<?>, Transformation<?>> transformations, Class<?> resourceClass, Class<?> transcodeClass, Options options) { this.model = Preconditions.checkNotNull(model); this.signature = Preconditions.checkNotNull(signature, "Signature must not be null"); this.width = width; this.height = height; this.transformations = Preconditions.checkNotNull(transformations); this.resourceClass = Preconditions.checkNotNull(resourceClass, "Resource class must not be null"); this.transcodeClass = Preconditions.checkNotNull(transcodeClass, "Transcode class must not be null"); this.options = Preconditions.checkNotNull(options); } @Override public boolean equals(Object o) { if (o instanceof EngineKey) { EngineKey other = (EngineKey) o; return model.equals(other.model) && signature.equals(other.signature) && height == other.height && width == other.width && transformations.equals(other.transformations) && resourceClass.equals(other.resourceClass) && transcodeClass.equals(other.transcodeClass) && options.equals(other.options); } return false; } @Override public int hashCode() { if (hashCode == 0) { hashCode = model.hashCode(); hashCode = 31 * hashCode + signature.hashCode(); hashCode = 31 * hashCode + width; hashCode = 31 * hashCode + height; hashCode = 31 * hashCode + transformations.hashCode(); hashCode = 31 * hashCode + resourceClass.hashCode(); hashCode = 31 * hashCode + transcodeClass.hashCode(); hashCode = 31 * hashCode + options.hashCode(); } return hashCode; } } 复制代码
//跳过内存缓存 RequestOptions requestOptions =new RequestOptions().skipMemoryCache(true); Glide.with(this).load(IMAGE_URL).apply(requestOptions).into(imageView); //Generated API 方式 GlideApp.with(this).load(IMAGE_URL).skipMemoryCache(true).into(imageView); //清除内存缓存,必须在主线程中调用 Glide.get(context).clearMemory(); 复制代码
/**Engine类的load方法*/ public <R> LoadStatus load(GlideContext glideContext,Object model, Key signature,int width,int height,Class<?> resourceClass,Class<R> transcodeClass,Priority priority,DiskCacheStrategy diskCacheStrategy,Map<Class<?>, Transformation<?>> transformations,boolean isTransformationRequired,boolean isScaleOnlyOrNoTransform, Options options,boolean isMemoryCacheable,boolean useUnlimitedSourceExecutorPool,boolean useAnimationPool,boolean onlyRetrieveFromCache,ResourceCallback cb) { //省略部分代码 .......... EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable); if (active != null) { cb.onResourceReady(active, DataSource.MEMORY_CACHE); if (VERBOSE_IS_LOGGABLE) { logWithTimeAndKey("Loaded resource from active resources", startTime, key); } return null; } //省略部分代码 .......... } 复制代码
private final ActiveResources activeResources; /**Engine类的loadFromActiveResources方法*/ @Nullable private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable) { if (!isMemoryCacheable) { return null; } EngineResource<?> active = activeResources.get(key); if (active != null) { active.acquire(); } return active; } /**ActiveResources类*/ final class ActiveResources { @VisibleForTesting final Map<Key, ResourceWeakReference> activeEngineResources = new HashMap<>(); //省略部分代码 ........ @VisibleForTesting static final class ResourceWeakReference extends WeakReference<EngineResource<?>> { //省略部分代码 ........ } } /**Engine类的onEngineJobComplete方法*/ @SuppressWarnings("unchecked") @Override public void onEngineJobComplete(EngineJob<?> engineJob, Key key, EngineResource<?> resource) { Util.assertMainThread(); // A null resource indicates that the load failed, usually due to an exception. if (resource != null) { resource.setResourceListener(key, this); if (resource.isCacheable()) { activeResources.activate(key, resource); } } jobs.removeIfCurrent(key, engineJob); } /**RequestOptions类的skipMemoryCache方法*/ public RequestOptions skipMemoryCache(boolean skip) { if (isAutoCloneEnabled) { return clone().skipMemoryCache(true); } this.isCacheable = !skip; fields |= IS_CACHEABLE; return selfOrThrowIfLocked(); } 复制代码
/**Engine类的load方法*/ public <R> LoadStatus load(GlideContext glideContext,Object model, Key signature,int width,int height,Class<?> resourceClass,Class<R> transcodeClass,Priority priority,DiskCacheStrategy diskCacheStrategy,Map<Class<?>, Transformation<?>> transformations,boolean isTransformationRequired,boolean isScaleOnlyOrNoTransform, Options options,boolean isMemoryCacheable,boolean useUnlimitedSourceExecutorPool,boolean useAnimationPool,boolean onlyRetrieveFromCache,ResourceCallback cb) { //省略部分代码 .......... EngineResource<?> cached = loadFromCache(key, isMemoryCacheable); if (cached != null) { cb.onResourceReady(cached, DataSource.MEMORY_CACHE); if (VERBOSE_IS_LOGGABLE) { logWithTimeAndKey("Loaded resource from cache", startTime, key); } return null; } //省略部分代码 .......... } /**Engine类的loadFromCache方法*/ private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) { if (!isMemoryCacheable) { return null; } EngineResource<?> cached = getEngineResourceFromCache(key); if (cached != null) { cached.acquire(); activeResources.activate(key, cached); } return cached; } /**Engine类的getEngineResourceFromCache方法*/ private final MemoryCache cache; private EngineResource<?> getEngineResourceFromCache(Key key) { Resource<?> cached = cache.remove(key); final EngineResource<?> result; if (cached == null) { result = null; } else if (cached instanceof EngineResource) { // Save an object allocation if we've cached an EngineResource (the typical case). result = (EngineResource<?>) cached; } else { result = new EngineResource<>(cached, true /*isMemoryCacheable*/, true /*isRecyclable*/); } return result; } /**GlideBuilder类的build方法*/ private MemoryCache cache; @NonNull Glide build(@NonNull Context context) { //省略部分代码 .......... if (memoryCache == null) { memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize()); } if (diskCacheFactory == null) { diskCacheFactory = new InternalCacheDiskCacheFactory(context); } if (engine == null) { engine = new Engine( memoryCache, diskCacheFactory, diskCacheExecutor, sourceExecutor, GlideExecutor.newUnlimitedSourceExecutor(), GlideExecutor.newAnimationExecutor(), isActiveResourceRetentionAllowed); } //省略部分代码 .......... } /**LruResourceCache类的实现继承关系*/ public class LruResourceCache extends LruCache<Key, Resource<?>> implements MemoryCache{......} 复制代码
/**EngineJob类的handleResultOnMainThread方法*/ @Synthetic void handleResultOnMainThread() { //省略部分代码 .......... engineResource = engineResourceFactory.build(resource, isCacheable); hasResource = true; //省略部分代码 .......... engineResource.acquire(); listener.onEngineJobComplete(this, key, engineResource); engineResource.release(); //省略部分代码 .......... } /**EngineJob类的EngineResourceFactory内部类*/ @VisibleForTesting static class EngineResourceFactory { public <R> EngineResource<R> build(Resource<R> resource, boolean isMemoryCacheable) { return new EngineResource<>(resource, isMemoryCacheable, /*isRecyclable=*/ true); } } /**Engine类的onEngineJobComplete方法*/ @SuppressWarnings("unchecked") @Override public void onEngineJobComplete(EngineJob<?> engineJob, Key key, EngineResource<?> resource) { //省略部分代码 .......... if (resource != null) { resource.setResourceListener(key, this); if (resource.isCacheable()) { activeResources.activate(key, resource); } } //省略部分代码 .......... } 复制代码
/**EngineResource类的acquire方法*/ void acquire() { if (isRecycled) { throw new IllegalStateException("Cannot acquire a recycled resource"); } if (!Looper.getMainLooper().equals(Looper.myLooper())) { throw new IllegalThreadStateException("Must call acquire on the main thread"); } ++acquired; } /**EngineResource类的release方法*/ void release() { if (acquired <= 0) { throw new IllegalStateException("Cannot release a recycled or not yet acquired resource"); } if (!Looper.getMainLooper().equals(Looper.myLooper())) { throw new IllegalThreadStateException("Must call release on the main thread"); } if (--acquired == 0) { listener.onResourceReleased(key, this); } } /**Engine类的onResourceReleased方法*/ @Override public void onResourceReleased(Key cacheKey, EngineResource<?> resource) { Util.assertMainThread(); activeResources.deactivate(cacheKey); if (resource.isCacheable()) { cache.put(cacheKey, resource); } else { resourceRecycler.recycle(resource); } } 复制代码
RequestOptions requestOptions = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE);//不使用缓存
Glide.with(Context).load(IMAGE_URL).apply(requestOptions).into(mImageView);
复制代码
/**DecodeJob类的start方法*/ public void start(DecodeJob<R> decodeJob) { this.decodeJob = decodeJob; GlideExecutor executor = decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor(); executor.execute(decodeJob); } /**DecodeJob类的willDecodeFromCache方法*/ boolean willDecodeFromCache() { Stage firstStage = getNextStage(Stage.INITIALIZE); return firstStage == Stage.RESOURCE_CACHE || firstStage == Stage.DATA_CACHE; } /**DecodeJob类的getNextStage方法*/ private Stage getNextStage(Stage current) { switch (current) { case INITIALIZE: return diskCacheStrategy.decodeCachedResource() ? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE); case RESOURCE_CACHE: return diskCacheStrategy.decodeCachedData() ? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE); case DATA_CACHE: return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE; //省略部分代码 ...... } } /**DiskCacheStrategy类的ALL对象*/ public static final DiskCacheStrategy ALL = new DiskCacheStrategy() { @Override public boolean isDataCacheable(DataSource dataSource) { return dataSource == DataSource.REMOTE; } @Override public boolean isResourceCacheable(boolean isFromAlternateCacheKey, DataSource dataSource, EncodeStrategy encodeStrategy) { return dataSource != DataSource.RESOURCE_DISK_CACHE && dataSource != DataSource.MEMORY_CACHE; } @Override public boolean decodeCachedResource() { return true; } @Override public boolean decodeCachedData() { return true; } }; /**GlideBuilder类的build方法*/ @NonNull Glide build(@NonNull Context context) { //省略部分代码 ...... if (diskCacheExecutor == null) { diskCacheExecutor = GlideExecutor.newDiskCacheExecutor(); } //省略部分代码 ...... } /**GlideExecutor类的newDiskCacheExecutor方法*/ private static final int DEFAULT_DISK_CACHE_EXECUTOR_THREADS = 1; public static GlideExecutor newDiskCacheExecutor() { return newDiskCacheExecutor( DEFAULT_DISK_CACHE_EXECUTOR_THREADS, DEFAULT_DISK_CACHE_EXECUTOR_NAME, UncaughtThrowableStrategy.DEFAULT); } /**GlideExecutor类的newDiskCacheExecutor方法*/ public static GlideExecutor newDiskCacheExecutor( int threadCount, String name, UncaughtThrowableStrategy uncaughtThrowableStrategy) { return new GlideExecutor( new ThreadPoolExecutor( threadCount /* corePoolSize */, threadCount /* maximumPoolSize */, 0 /* keepAliveTime */, TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>(), new DefaultThreadFactory(name, uncaughtThrowableStrategy, true))); } 复制代码
/**GlideBuilder类的build方法*/ private DiskCache.Factory diskCacheFactory; @NonNull Glide build(@NonNull Context context) { //省略部分代码 .......... if (diskCacheFactory == null) { diskCacheFactory = new InternalCacheDiskCacheFactory(context); } //省略部分代码 .......... } /**InternalCacheDiskCacheFactory类的继承关系*/ public final class InternalCacheDiskCacheFactory extends DiskLruCacheFactory { //省略实现代码 .......... } /**DiskLruCacheFactory类的部分代码*/ public class DiskLruCacheFactory implements DiskCache.Factory { //省略部分代码 .......... @Override public DiskCache build() { File cacheDir = cacheDirectoryGetter.getCacheDirectory(); //省略部分代码 .......... return DiskLruCacheWrapper.create(cacheDir, diskCacheSize); } } /**DiskLruCacheWrapper类的部分代码*/ public class DiskLruCacheWrapper implements DiskCache { //省略部分代码 .......... private synchronized DiskLruCache getDiskCache() throws IOException { if (diskLruCache == null) { diskLruCache = DiskLruCache.open(directory, APP_VERSION, VALUE_COUNT, maxSize); } return diskLruCache; } //省略部分代码 .......... } /**DiskLruCache类的部分代码*/ public final class DiskLruCache implements Closeable { //省略部分代码 .......... public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize) throws IOException { DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); //省略部分代码 .......... return cache; } //省略部分代码 .......... } 复制代码
/**DecodeJob的getNextGenerator方法*/ private DataFetcherGenerator getNextGenerator() { switch (stage) { case RESOURCE_CACHE: return new ResourceCacheGenerator(decodeHelper, this); case DATA_CACHE: return new DataCacheGenerator(decodeHelper, this); case SOURCE: return new SourceGenerator(decodeHelper, this); case FINISHED: return null; default: throw new IllegalStateException("Unrecognized stage: " + stage); } } 复制代码
/** ResourceCacheGenerator类的startNext方法*/ @SuppressWarnings("PMD.CollapsibleIfStatements") @Override public boolean startNext() { //省略部分代码 .......... currentKey = new ResourceCacheKey(// NOPMD AvoidInstantiatingObjectsInLoops helper.getArrayPool(), sourceId, helper.getSignature(), helper.getWidth(), helper.getHeight(), transformation, resourceClass, helper.getOptions()); cacheFile = helper.getDiskCache().get(currentKey); if (cacheFile != null) { sourceKey = sourceId; modelLoaders = helper.getModelLoaders(cacheFile); modelLoaderIndex = 0; } } loadData = null; boolean started = false; while (!started && hasNextModelLoader()) { ModelLoader<File, ?> modelLoader = modelLoaders.get(modelLoaderIndex++); loadData = modelLoader.buildLoadData(cacheFile, helper.getWidth(), helper.getHeight(), helper.getOptions()); if (loadData != null && helper.hasLoadPath(loadData.fetcher.getDataClass())) { started = true; loadData.fetcher.loadData(helper.getPriority(), this); } } return started; } /**DecodeHelper类的getDiskCache方法*/ DiskCache getDiskCache() { return diskCacheProvider.getDiskCache(); } /** LazyDiskCacheProvider类的getDiskCache方法 */ @Override public DiskCache getDiskCache() { if (diskCache == null) { synchronized (this) { if (diskCache == null) { diskCache = factory.build(); } if (diskCache == null) { diskCache = new DiskCacheAdapter(); } } } return diskCache; } 复制代码
/** ResourceCacheGenerator类的startNext方法*/ @Override public void onDataReady(Object data) { cb.onDataFetcherReady(sourceKey, data, loadData.fetcher, DataSource.RESOURCE_DISK_CACHE, currentKey); } 复制代码
/** DataCacheGenerator类的startNext方法*/ @Override public boolean startNext() { //省略部分代码 .......... Key originalKey = new DataCacheKey(sourceId, helper.getSignature()); cacheFile = helper.getDiskCache().get(originalKey); if (cacheFile != null) { this.sourceKey = sourceId; modelLoaders = helper.getModelLoaders(cacheFile); modelLoaderIndex = 0; } } loadData = null; boolean started = false; while (!started && hasNextModelLoader()) { ModelLoader<File, ?> modelLoader = modelLoaders.get(modelLoaderIndex++); loadData = modelLoader.buildLoadData(cacheFile, helper.getWidth(), helper.getHeight(), helper.getOptions()); if (loadData != null && helper.hasLoadPath(loadData.fetcher.getDataClass())) { started = true; loadData.fetcher.loadData(helper.getPriority(), this); } } return started; } /** DataCacheGenerator类的onDataReady方法*/ @Override public void onDataReady(Object data) { cb.onDataFetcherReady(sourceKey, data, loadData.fetcher, DataSource.DATA_DISK_CACHE, sourceKey); } 复制代码
/** DecodeJob类的decodeFromRetrievedData方法*/ private void decodeFromRetrievedData() { //省略部分代码 .......... notifyEncodeAndRelease(resource, currentDataSource); //省略部分代码 .......... } /** DecodeJob类的notifyEncodeAndRelease方法*/ private final DeferredEncodeManager<?> deferredEncodeManager = new DeferredEncodeManager<>(); private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) { //省略部分代码 .......... stage = Stage.ENCODE; try { if (deferredEncodeManager.hasResourceToEncode()) { deferredEncodeManager.encode(diskCacheProvider, options); } } //省略部分代码 .......... } /** DeferredEncodeManager类的encode方法**/ void encode(DiskCacheProvider diskCacheProvider, Options options) { GlideTrace.beginSection("DecodeJob.encode"); try { diskCacheProvider.getDiskCache().put(key, new DataCacheWriter<>(encoder, toEncode, options)); } finally { toEncode.unlock(); GlideTrace.endSection(); } } 复制代码
/**SourceGenerator类的onDataReady方法**/ private Object dataToCache; @Override public void onDataReady(Object data) { DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy(); if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) { dataToCache = data; cb.reschedule(); } else { cb.onDataFetcherReady(loadData.sourceKey, data, loadData.fetcher, loadData.fetcher.getDataSource(), originalKey); } } /**SourceGenerator类的startNext方法**/ @Override public boolean startNext() { if (dataToCache != null) { Object data = dataToCache; dataToCache = null; cacheData(data); } if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) { return true; } //省略部分代码 .......... } /**SourceGenerator类的cacheData方法**/ private void cacheData(Object dataToCache) { long startTime = LogTime.getLogTime(); try { Encoder<Object> encoder = helper.getSourceEncoder(dataToCache); DataCacheWriter<Object> writer = new DataCacheWriter<>(encoder, dataToCache, helper.getOptions()); originalKey = new DataCacheKey(loadData.sourceKey, helper.getSignature()); helper.getDiskCache().put(originalKey, writer); } //省略部分代码 .......... sourceCacheGenerator = new DataCacheGenerator(Collections.singletonList(loadData.sourceKey), helper, this); } /**DecodeJob类的reschedule方法**/ @Override public void reschedule() { runReason = RunReason.SWITCH_TO_SOURCE_SERVICE; callback.reschedule(this); } /**Engine类的reschedule方法**/ @Override public void reschedule(DecodeJob<?> job) { getActiveSourceExecutor().execute(job); } 复制代码
RequestOptions requestOptions = new RequestOptions().onlyRetrieveFromCache(true); Glide.with(this).load(IMAGE_URL).apply(requestOptions).into(mImageView); //Generated API 方式 GlideApp.with(this) .load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(mImageView); 复制代码
/**DecodeJob类的getNextStage方法**/ private Stage getNextStage(Stage current) { switch (current) { //省略部分代码 .......... case DATA_CACHE: return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE; case SOURCE: case FINISHED: return Stage.FINISHED; } } /**DecodeJob类的getNextGenerator方法**/ private DataFetcherGenerator getNextGenerator() { switch (stage) { //省略部分代码 .......... case FINISHED: return null; default: throw new IllegalStateException("Unrecognized stage: " + stage); } } 复制代码
/**SingleRequest类的onResourceReady方法**/ @Nullable private List<RequestListener<R>> requestListeners; private void onResourceReady(Resource<R> resource, R result, DataSource dataSource) { //省略部分代码 .......... isCallingCallbacks = true; try { boolean anyListenerHandledUpdatingTarget = false; //省略部分代码 .......... if (!anyListenerHandledUpdatingTarget) { Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource); target.onResourceReady(result, animation); } } //省略部分代码 .......... } /**Target 接口**/ public interface Target<R> extends LifecycleListener {} /**ImageViewTarget类的onResourceReady方法**/ @Override public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) { if (transition == null || !transition.transition(resource, this)) { setResourceInternal(resource); } else { maybeUpdateAnimatable(resource); } } /**ImageViewTarget类的setResourceInternal方法**/ private void setResourceInternal(@Nullable Z resource) { setResource(resource); maybeUpdateAnimatable(resource); } DrawableImageViewTarget /**DrawableImageViewTarget类的setResource方法**/ @Override protected void setResource(@Nullable Drawable resource) { view.setImageDrawable(resource); } 复制代码
Glide.with(this).load(IMAGE_URL).listener(new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { return false; } }).into(mImageView); 复制代码
/**RequestBuilder类的listener方法**/ @Nullable private List<RequestListener<TranscodeType>> requestListeners; public RequestBuilder<TranscodeType> listener( @Nullable RequestListener<TranscodeType> requestListener) { this.requestListeners = null; return addListener(requestListener); } /**RequestBuilder类的addListener方法**/ public RequestBuilder<TranscodeType> addListener( @Nullable RequestListener<TranscodeType> requestListener) { if (requestListener != null) { if (this.requestListeners == null) { this.requestListeners = new ArrayList<>(); } this.requestListeners.add(requestListener); } return this; } /**SingleRequest类的onResourceReady方法**/ @Nullable private List<RequestListener<R>> requestListeners; private void onResourceReady(Resource<R> resource, R result, DataSource dataSource) { //省略部分代码 .......... isCallingCallbacks = true; try { boolean anyListenerHandledUpdatingTarget = false; if (requestListeners != null) { for (RequestListener<R> listener : requestListeners) { anyListenerHandledUpdatingTarget |= listener.onResourceReady(result, model, target, dataSource, isFirstResource); } } anyListenerHandledUpdatingTarget |= targetListener != null && targetListener.onResourceReady(result, model, target, dataSource, isFirstResource); if (!anyListenerHandledUpdatingTarget) { Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource); target.onResourceReady(result, animation); } } //省略部分代码 .......... } 复制代码
//注意须要指定Glide的加载类型asBitmap,不指定Target不知道自己是是类型的Target
Glide.with(this).asBitmap().load(IMAGE_URL).into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
//加载完成已经在主线程
mImageView.setImageBitmap(resource);
}
});
复制代码
/** * @author maoqitian * @Description: 自定义RelativeLayout * @date 2019/2/18 0018 19:51 */ public class MyView extends RelativeLayout { private ViewTarget<MyView, Drawable> viewTarget; public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); viewTarget =new ViewTarget<MyView, Drawable>(this) { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { setBackground(resource); } }; } public ViewTarget<MyView, Drawable> getViewTarget() { return viewTarget; } } //使用Glide加载 MyView rl_view = findViewById(R.id.rl_view); Glide.with(this).load(IMAGE_URL).into(rl_view.getViewTarget()); 复制代码
new Thread(new Runnable() { @Override public void run() { FutureTarget<File> target = null; RequestManager requestManager = Glide.with(MainActivity.this); try { target = requestManager .downloadOnly() .load(IMAGE_URL) .submit(); final File downloadedFile = target.get(); Log.i(TAG,"缓存文件路径"+downloadedFile.getAbsolutePath()); } catch (ExecutionException | InterruptedException e) { } finally { if (target != null) { target.cancel(true); // mayInterruptIfRunning } } } }).start(); 复制代码
Glide.with(this).load(IMAGE_URL).preload();
复制代码
/**RequestBuilder类的preload方法**/ @NonNull public Target<TranscodeType> preload() { return preload(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL); } /**RequestBuilder类的preload方法**/ @NonNull public Target<TranscodeType> preload(int width, int height) { final PreloadTarget<TranscodeType> target = PreloadTarget.obtain(requestManager, width, height); return into(target); } /**RequestBuilder类的onResourceReady方法**/ public final class PreloadTarget<Z> extends SimpleTarget<Z> { private static final Handler HANDLER = new Handler(Looper.getMainLooper(), new Callback() { @Override public boolean handleMessage(Message message) { if (message.what == MESSAGE_CLEAR) { ((PreloadTarget<?>) message.obj).clear(); return true; } return false; } }); //省略部分代码 .......... public static <Z> PreloadTarget<Z> obtain(RequestManager requestManager, int width, int height) { return new PreloadTarget<>(requestManager, width, height); } @Override public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) { HANDLER.obtainMessage(MESSAGE_CLEAR, this).sendToTarget(); } //省略部分代码 .......... } 复制代码
//在app下的gradle添加Glide注解处理器的依赖 dependencies { annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0' } //新建一个类集成AppGlideModule并添加上@GlideModule注解,从新rebuild项目就可使用GlideApp了 @GlideModule public final class MyAppGlideModule extends AppGlideModule {} 复制代码
/**GlideApp类部分代码**/ public final class GlideApp { //省略部分代码 .......... @NonNull public static GlideRequests with(@NonNull Context context) { return (GlideRequests) Glide.with(context); } //省略部分代码 .......... } /**GlideApp类部分代码**/ public class GlideRequest<TranscodeType> extends RequestBuilder<TranscodeType> implements Cloneable { //省略部分代码 .......... @NonNull @CheckResult public GlideRequest<TranscodeType> placeholder(@Nullable Drawable drawable) { if (getMutableOptions() instanceof GlideOptions) { this.requestOptions = ((GlideOptions) getMutableOptions()).placeholder(drawable); } else { this.requestOptions = new GlideOptions().apply(this.requestOptions).placeholder(drawable); } return this; } //省略部分代码 .......... } /**RequestBuilder类的getMutableOptions方法**/ protected RequestOptions getMutableOptions() { return defaultRequestOptions == this.requestOptions ? this.requestOptions.clone() : this.requestOptions; } 复制代码
/** * @author maoqitian * @Description: GlideApp 功能扩展类 * @date 2019/2/19 0019 12:51 */ @GlideExtension public class MyGlideExtension { private MyGlideExtension() { } //能够为方法任意添加参数,但要保证第一个参数为 RequestOptions /** * 设置通用的加载占位图和错误加载图 * @param options */ @GlideOption public static void normalPlaceholder(RequestOptions options) { options.placeholder(R.drawable.ic_cloud_download_black_24dp).error(R.drawable.ic_error_black_24dp); } } /**GlideOptions类中生成对应的方法**/ /** * @see MyGlideExtension#normalPlaceholder(RequestOptions) */ @CheckResult @NonNull public GlideOptions normalPlaceholder() { if (isAutoCloneEnabled()) { return clone().normalPlaceholder(); } MyGlideExtension.normalPlaceholder(this); return this; } /**GlideRequest类中生成对应的方法**/ /** * @see GlideOptions#normalPlaceholder() */ @CheckResult @NonNull public GlideRequest<TranscodeType> normalPlaceholder() { if (getMutableOptions() instanceof GlideOptions) { this.requestOptions = ((GlideOptions) getMutableOptions()).normalPlaceholder(); } else { this.requestOptions = new GlideOptions().apply(this.requestOptions).normalPlaceholder(); } return this; } 复制代码
//调用咱们刚刚设置的扩展功能方法
GlideApp.with(this).load(IMAGE_URL)
.normalPlaceholder()
.into(mImageView);
复制代码
@GlideExtension public class MyGlideExtension { private static final RequestOptions DECODE_TYPE_GIF = decodeTypeOf(GifDrawable.class).lock(); @GlideType(GifDrawable.class) public static void asMyGif(RequestBuilder<GifDrawable> requestBuilder) { requestBuilder .transition(new DrawableTransitionOptions()) .apply(DECODE_TYPE_GIF); } } /**GlideRequests类中生成的asMyGif方法**/ /** * @see MyGlideExtension#asMyGif(RequestBuilder) */ @NonNull @CheckResult public GlideRequest<GifDrawable> asMyGif() { GlideRequest<GifDrawable> requestBuilder = this.as(GifDrawable.class); MyGlideExtension.asMyGif(requestBuilder); return requestBuilder; } 复制代码
GlideApp.with(this).asMyGif().load(IMAGE_URL) .into(mImageView); 复制代码