前言
在《Glide源码解析(1)—图片加载流程》一文中主要分析了Glide如何从网络下载并设置到ImageView上加载流程。
在《Glide源码解析(2)—Glide实例创建过程》一文中主要分析了Glide的创建流程,包括内存缓存和磁盘缓存的初始化。
其中缓存加载机制并没有过多分析,本文就专门分析一下Glide中缓存的加载流程是如何设计的。
设置缓存
Glide.with(this)
.load("https://url")
.diskCacheStrategy(DiskCacheStrategy.ALL)
.skipMemoryCache(false)
.into(iv_glide);
设置内存缓存
-
skipMemoryCache
是否设置内存缓存。
设置磁盘缓存
-
DiskCacheStrategy.ALL
缓存SOURCE和RESULT两种图片。
-
DiskCacheStrategy.NONE
不设置磁盘缓存。
-
DiskCacheStrategy.SOURCE
缓存SOURCE类型图片,即原图。
-
DiskCacheStrategy.RESULT
缓存RESULT类型图片,即处理后的图片。
缓存初始化
Glide的缓存可以分为二级缓存也可以分为三级缓存,二级缓存的话就是内存缓存和磁盘缓存,三级缓存的话就是活动内存缓存和非活动内存缓存以及磁盘缓存,缓存的初始化是在Glide实例创建的时候做的,找到GlideBuilder
类的createGlide
方法,如下所示:
Glide createGlide() {
// 创建资源加载线程池
if (sourceService == null) {
final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
sourceService = new FifoPriorityThreadPoolExecutor(cores);
}
// 创建磁盘缓存线程池
if (diskCacheService == null) {
diskCacheService = new FifoPriorityThreadPoolExecutor(1);
}
//创建bitmap池
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
if (bitmapPool == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
int size = calculator.getBitmapPoolSize();
bitmapPool = new LruBitmapPool(size);
} else {
bitmapPool = new BitmapPoolAdapter();
}
}
// 创建内存缓存
if (memoryCache == null) {
memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
}
// 创建磁盘缓存
if (diskCacheFactory == null) {
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}
//创建Engine
if (engine == null) {
engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
}
// 设置默认图片格式
if (decodeFormat == null) {
decodeFormat = DecodeFormat.DEFAULT;
}
// 创建Glie实例
return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
}
从源码可以得知内存缓存创建的是LruResourceCache
类,磁盘缓存创建的是InternalCacheDiskCacheFactory
类。
LruResourceCache类
public class LruResourceCache extends LruCache<Key, Resource<?>> implements MemoryCache {
......
}
LruResourceCache
类继承了AndroidSDK中的LruCache
,LRU全称为Least Recently Used
,即最近最少使用。
LRU算法就是当缓存空间满了的时候,将最近最少使用的数据从缓存空间中删除,以增加可用的缓存空间来缓存新数据。
这个算法的内部有一个LinkedHashMap
类型的缓存列表,每当一个缓存数据被访问的时候,这个数据就会被提到列表尾部,每次都这样的话,列表的头部数据就是最近最不常使用的了,当缓存空间不足时,就会删除列表头部的缓存数据。
InternalCacheDiskCacheFactory类
public final class InternalCacheDiskCacheFactory extends DiskLruCacheFactory {
public InternalCacheDiskCacheFactory(Context context) {
this(context, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR,
DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);
}
}
从源码可以看到InternalCacheDiskCacheFactory
类继承了DiskLruCacheFactory
类,并在构造方法中传入了DEFAULT_DISK_CACHE_DIR
和DEFAULT_DISK_CACHE_SIZE
,找到这俩常量:
interface Factory {
/** 250 MB of cache. */
int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;
String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
/**
* Returns a new disk cache, or {@code null} if no disk cache could be created.
*/
DiskCache build();
}
可以得知,Glide默认磁盘缓存大小是250M,默认缓存目录名称是image_manager_disk_cache
。InternalCacheDiskCacheFactory
类继承了DiskLruCacheFactory
类,后面再看这个父类。
缓存加载流程
在《Glide源码解析—图片加载流程》一文中,可以得知缓存的加载流程,在Engin
类的load
方法中:
public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy,