注:为了突出重点,文中的源码有大量删节,有的用//..进行了标识,有的没有。
引子
图片加载
Engine#load()
public <R> LoadStatus load(//..) {
//..
// 一级内存缓存
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
//..
return null;
}
// 二级内存内存
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
//..
return null;
}
//..
}
ActiveResources解析
获取 ActiveResource 缓存
Engine#loadFromActiveResources()
private final ActiveResources activeResources;
@Nullable
private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable) {
//..
EngineResource<?> active = activeResources.get(key);
//..
return active;
}
ActiveResource
本质是一个HashMap,用WeekReference保存EngineResource,用作内存缓存。
final class ActiveResources {
final Map<Key, ResourceWeakReference> activeEngineResources = new HashMap<>();
static final class ResourceWeakReference extends WeakReference<EngineResource<?>> {
//..
}
void activate(Key key, EngineResource<?> resource) {
ResourceWeakReference toPut = new ResourceWeakReference(//..)
ResourceWeakReference removed = activeEngineResources.put(key, toPut);
//..
}
void deactivate(Key key) {
ResourceWeakReference removed = activeEngineResources.remove(key);
if (removed != null) {
removed.reset();
}
}
EngineResource<?> get(Key key) {
ResourceWeakReference activeRef = activeEngineResources.get(key);
//..
return active;
}
}
ActiveResources 缓存的添加和移除
从调用关系可以看到activate是在EngineJobComplete或loadFromcache时调用的,deactivate是在onResourceRelease时调用的。调用都是在Engine中,可见ActiveResources的维护都是有Engine维护的。


MemoryCache 解析
获取 MemoryCache 缓存
Engine#loadFromCache
private final MemoryCache cache;
private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {
//..
EngineResource<?> cached = getEngineResourceFromCache(key);
//..
return cached;
}
private EngineResource<?> getEngineResourceFromCache(Key key) {
Resource<?> cached = cache.remove(key);
//..
return result;
}
MemoryCache 的具体实现
MemoryCache 是一个接口, 默认的实现是LruResourceCache。 初始化逻辑: GlideBuilder#build
@NonNull
Glide build(@NonNull Context context) {
//..
if (memoryCache == null) {
memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
}
if (engine == null) {
engine =
new Engine(
memoryCache,
//..);
}
//..
}
LruResourceCache 的继承结构
LruResourceCache extends LruCache<Key, Resource<?>> implements MemoryCache
MemoryCache 缓存的添加和移除
加入是在onResourceReleased,联系前面的源码只可以看到,在onResourceReleased中cache从ActiveResource中移出来,放到LruResourceCache中了。
移出是在getEngineResourceFromCache()中,从LruResourceCache移到ActiveResource中,刚好对应。


再来回顾一下Glide内存缓存的逻辑
onEngineJobComplete 图片被缓存到ActiveResources
onResourceReleased 图片从ActiveResources移到LruResourceCache
loadFromCache 图片从LruResourceCache移到ActiveResources
@Override
public void onEngineJobComplete(EngineJob<?> engineJob, Key key, EngineResource<?> resource) {
//..
if (resource.isCacheable()) {
activeResources.activate(key, resource);
}
}
@Override
public void onResourceReleased(Key cacheKey, EngineResource<?> resource) {
activeResources.deactivate(cacheKey);
//..
cache.put(cacheKey, resource);
//..
}
private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {
//..
EngineResource<?> cached = getEngineResourceFromCache(key);
activeResources.activate(key, cached);
return cached;
}
private EngineResource<?> getEngineResourceFromCache(Key key) {
Resource<?> cached = cache.remove(key);
//..
}
回顾Engine、ActivityResources、LruCacheResourceCache
从上面的分析可以看到,cache的加入和移除都是通过Engine的回调方法进行处理的,也就是说Engine监听图片加载过程中的各种事件,在事件发生的时候采取相应的行动维护缓存。Engine实现了3个interface,一个这对图片加载任务,一个针对ActiveResources,一个针对LruCacheResourceCache,结构非常清晰。
public class Engine implements EngineJobListener,
MemoryCache.ResourceRemovedListener,
EngineResource.ResourceListener{}
interface EngineJobListener {
void onEngineJobComplete(EngineJob<?> engineJob, Key key, EngineResource<?> resource);
void onEngineJobCancelled(EngineJob<?> engineJob, Key key);
}
MemoryCache
interface ResourceRemovedListener {
void onResourceRemoved(@NonNull Resource<?> removed);
}
EngineResource
interface ResourceListener {
void onResourceReleased(Key key, EngineResource<?> resource);
}