active.acquire();
}
return active;
}
// EngineResource.java
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;
}
如果返回的 active不为null,则调用 active.acquire()
,它的作用是给计数器 acquired自增1(在主线程和非回收状态下),这里并不知道为什么要这么做。所以就回去了。这样loadFromActiveResources()
就分析完了,往下走:
//Engine.java #load
…
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;
}
…
从 loadFromCache()
中获取EngineResource,如果拿得到就调用 onResourceRead()
返回。来看下这个方法:
// Engine.java
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;
}
这个方法和之前的 loadFromActiveResources
差别不大,先看看 getEngineResourceFromCache(key)
:
// Engine.java
private final MemoryCache cache;
private EngineResource<?> getEngineResourceFromCache(Key key) {
Resource<?> cached = cache.remove(key); // 1
final EngineResource<?> result;
if (cached == null) {
result = null;
} else if (cached instanceof EngineResource) {
result = (EngineResource<?>) cached;
} else {
result = new EngineResource<>(cached, true /isMemoryCacheable/, true /isRecyclable/);
}
return result;
}
这个方法就是从 MemoryCache
中拿出一个EngineResource并返回。那我们要去看看 MemoryCache做了啥,但是MemoryCache是一个接口类,没有实现,在向前找的时候发现它是在创建 Glide initalizeGlide() 的过程中创建的,这里直接看创建的代码:
// GlideBuilder.java
@NonNull
Glide build(@NonNull Context context) {
…
if (memoryCache == null) {
memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
}
…
}
// LruResourceCache.java
public class LruResourceCache extends LruCache<Key, Resource<?>> implements MemoryCache {
…
}
LruResourceCache
实现了MemoryCache,并继承了LruCache。
这里简单的描述一下LruCache,它是最近最少使用策略,实现原理是 accessOrder为true的 LinkedHashMap。所以在getEngineResourceFromCache
的注释1中,它就是调用了 LinkedHashMap.remove(key)
来看Map中是否有key对应的 EngineResources。
回到 loadFromCache中:
// Engine.java #loadFromCache
…
EngineResource<?> cached = getEngineResourceFromCache(key);
if (cached != null) {
cached.acquire();
activeResources.activate(key, cached);
}
…
如果remove到的资源是不为null的,则调用 acquire()方法,并且调用 activeResources.activate(key, cached)
,我们看看这个方法做了什么:
// ActiveResources.java
void activate(Key key, EngineResource<?> resource) {
ResourceWeakReference toPut =
new ResourceWeakReference(
key,
resource,
getReferenceQueue(),
isActiveResourceRetentionAllowed);
ResourceWeakReference removed = activeEngineResources.put(key, toPut);
if (removed != null) {
removed.reset();
}
}
它把 key和EngineResource作为元素 put到了 ActiveResources的 HashMap中。便于以后 loadFromActiveResources
去拿。
然后最后return为null。 loadFromCache()
就结束了。可以看出来 LruCache也是在运行时产生的,所以它也是内存缓存。
这里出现了一个问题,这里出现了两个内存缓存,一个是HashMap缓存,一个是LruResourcesCache的缓存,在前者拿资源拿不到的情况下,去拿后者,如果后者拿到了,会把该资源放到前者中缓存。乍一看是没事找事,为什么不把所有的资源都放在一个cache下存储呢?这需要往后面的代码看。
接下来继续load()函数中:
private final Jobs jobs;
// Engine.java #load
…
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
current.addCallback(cb);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey(“Added to existing load”, startTime, key);
}
return new LoadStatus(cb, current);
}
…
通过 Jobs去拿一个 EngineJob
,如果 EngineJob不为null,则调用其 addCallback()
,这个方法最终也会调用 onResourceReady()
,并返回一个 LoadStatus
。先来看看 jobs的get方法:
// Jobs.java
private final Map<Key, EngineJob<?>> jobs = new HashMap<>();
private final Map<Key, EngineJob<?>> onlyCacheJobs = new HashMap<>();
EngineJob<?> get(Key key, boolean onlyRetrieveFromCache) {
return getJobMap(onlyRetrieveFromCache).get(key);
}
private Map<Key, EngineJob<?>> getJobMap(boolean onlyRetrieveFromCache) { <