Glide load源码、缓存机制分析,Android框架体系架构的知识

…EngineResource<?> cached = getEngineResourceFromCache(key);if (cached != null) {cached.acquire();activeResources.activate(key, cached);}…如果remove到的资源是不为null的,则调用 acquire()方法,并且调用 activeResources.activate(key, cached),我们看看这个方法做了什么:// ActiveRe
摘要由CSDN通过智能技术生成

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

return onlyRetrieveFromCache ? onlyCacheJobs : jobs;

}

onlyRetrieveFromCache这个字段中文意思为:是否只从Cache中搜索。默认情况下是 false。它就会去 jobs这个HashMap中拿EngineJob。这里也是一个缓存,但他并不是之间缓存图片资源。

EngineJob它不是一个图片资源,那它是什么呢?这里还不是很清晰,先往load下面走,

// Engine.java #load

EngineJob engineJob =

engineJobFactory.build(

key,

isMemoryCacheable,

useUnlimitedSourceExecutorPool,

useAnimationPool,

onlyRetrieveFromCache);

DecodeJob decodeJob =

decodeJobFactory.build(

glideContext,

model,

key,

signature,

width,

height,

resourceClass,

transcodeClass,

priority,

diskCacheStrategy,

transformations,

isTransformationRequired,

isScaleOnlyOrNoTransform,

onlyRetrieveFromCache,

options,

engineJob);

jobs.put(key, engineJob);

engineJob.addCallback(cb);

engineJob.start(decodeJob);

这里是load方法的最后一步,在上述三种缓存都命中不到资源的情况下,会创建一个 EngineJob和一个 DecodeJob,将 key和engineJob一起绑定加入到 Jobs的HashMap,这样之后上面的jobs缓存就有资源可以找,然后调用 EngineJob.addCallbackEngine.start()

这里的重点是 start方法,它是没有内存缓存后,去做的事情,所以这里算是一个新的开始。 也就是说,load可以看成两个部分,这里开始就是第二个部分。

1.2 EngineJob的start方法解析


// EngineJob.java

private final GlideExecutor diskCacheExecutor;

private final GlideExecutor sourceExecutor;

private final GlideExecutor sourceUnlimitedExecutor;

private final GlideExecutor animationExecutor;

public void start(DecodeJob decodeJob) {

this.decodeJob = decodeJob;

GlideExecutor executor = decodeJob.willDecodeFromCache()

? diskCacheExecutor
getActiveSourceExecutor();

executor.execute(decodeJob);

}

EngineJob里面有线程池执行器 GlideExecutor,它就是一个ExecutorService,因为加载图片是一个耗时操作,所以放到子线程做,所以这里出现了 Executor,其次,在EngineJob中,exeutor执行器并不是只有一个:

它会先根据缓存策略,拿到对应executor,比如这里的 :

// EngineJob.java

GlideExecutor executor = decodeJob.willDecodeFromCache()

? diskCacheExecutor
getActiveSourceExecutor();

就会根据 “是否在Cache中解码” 这个条件来拿 disCacheExecutor,还是其他三个中的执行器。

在默认情况下, DiskCacheStategey是 AUTOMATIC的,这里就是true,即用的是 diskCacheExecutor。

接下来就会拿着这个线程执

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值