注:为了突出重点,文中的源码有大量删节,有的用//..进行了标识,有的没有。
引子
图片加载
Engine#load()
publicLoadStatus 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 MapactiveEngineResources = new HashMap<>(); static final class ResourceWeakReference extends WeakReference > { //.. } 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> 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);}MemoryCacheinterface ResourceRemovedListener { void onResourceRemoved(@NonNull Resource removed);}EngineResourceinterface ResourceListener { void onResourceReleased(Key key, EngineResource resource);}复制代码