Glide load源码、缓存机制分析(1)

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) { <

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值