一、内存缓存
底层运用了近期最少使用的算法(LruCache算法)以及弱引用机制共同实现。如果能从内存缓存中读取到需要加载的图片,就直接进行回调(cb.onResourceReady),否则,才会开启线程去加载图片。
Glide.with(this)
.load(url)
.skipMemoryCache(true)//设置内循缓存,默认是开启的;当设置为true:禁用内存缓存
.into(imageView);
缓存key值:
在Engine的load()中:
public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
...
// 获取图片的唯一标示,比如网络图片的url
final String id = fetcher.getId();
// 构建一个缓存的key值,EngineKay对象
EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
transcoder, loadProvider.getSourceEncoder());
// 获取图片的缓存
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
// 如果有缓存就直接调用GenericRequest的onResourceReady()
cb.onResourceReady(cached);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
// 没有获取到图片的缓存
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
cb.onResourceReady(active);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
...
}
缓存方式的选择:
public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
...
// 获取图片的缓存1(使用LruCache算法)
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
// 如果有缓存就直接调用GenericRequest的onResourceReady()
cb.onResourceReady(cached);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
// 获取图片的缓存2(使用弱引用)
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
cb.onResourceReady(active);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
...
}
使用LruCache算法
private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {
// 这里的isMemoryCacheable就是skipMemoryCache中传入的boolean值
if (!isMemoryCacheable) {
return null;
}
EngineResource<?> cached = getEngineResourceFromCache(key);
if (cached != null) {
cached.acquire();
// 将这个缓存图片添加到activeResorce集合中(这是一个弱引用的map),主要是为了保证正在使用中的图片不被LruCache算法回收掉
activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));
}
return cached;
}
@SuppressWarnings("unchecked")
private EngineResource<?> getEngineResourceFromCache(Key key) {
// 通过分析这里的cached就是构建Glide对象时创建的LruResourceCache,说明这里是用的是LruCache算法
// 这里就是等我们获取到缓存中的图片以后会将他从缓存中移除掉
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 /*isCacheable*/);
}
return result;
}
使用弱引用
private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable) {
if (!isMemoryCacheable) {
return null;
}
EngineResource<?> active = null;
// 从弱引用的集合中取值
WeakReference<EngineResource<?>> activeRef = activeResources.get(key);
if (activeRef != null) {
active = activeRef.get();
if (active != null) {
active.acquire();
} else {
activeResources.remove(key);
}
}
return active;
}
内存缓存图片加载完成后的写入:
1、写入到弱引用的缓存: