前两篇主要介绍了Glide的缓存机制和注册器,但是这两篇并不是Glide的核心功能,只能算是深入了解Glide的铺垫工作。调用流程的理解,会让你深入的了解Glide的工作过程和源码,这篇开始,我们正式进入Glide的核心部分。
Glide的调用流程,相对比较复杂,涉及的类和方法都比较多,如果直接进入源码一步一步的待着大家看,可能看到后面,前面的就忘记了,所以我这里画了一张调用Glide加载图片时其内部的流程,如下图,直接看图可能会懵,所以一定要结合下面的解释一起理解:
Glide.with(this).load(filePath).into(iamgeView);
Glide的调用最简单的就是上面的用法,上图呢就是以此流程用法为例进行解析。
第一部分:
从调用类执行Glide.with开始,一直到into方法调用之前,其实都是比较简单的。虽然我们暂时还不清楚RequestManagerRetriever,RequestManagerFragment,RequestManager这三个类是干嘛的,但是并不影响我们之后流程的理解,你会发现,into之后的流程基本和这三个类没有关系。
第二部分:
into方法是RequestBuilder类中的方法,这个方法的内部会创建一个Request对象,进入Request这个类你会发现,它其实是一个接口类,那接口类是谁呢?
Request request = buildRequest(target, targetListener, options);
我们从into方法中的这句代码层层的往上找,最后定位在obtainRequest方法中
return SingleRequest.obtain(...);
所以我们确定这个Request的实现类,其实是SingleRequest
在into方法的最后,调用了RequestManager对象的trace方法,出入了ImageView对象和SingleRequest对象
void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
targetTracker我们暂时忽略,我们主要看requestTracker.runReqeust方法。内部代码很简单,调用了SingleRequest对象的begin方法(如上图中的begin方法),begin方法内部调用了自己的onSizeReady方法,然后调用了Engine对象的load方法
第三部分:
到了这里,就到了我们前两篇提到的内存缓存了,内存缓存包括了活动缓存和内存缓存。我们直接看代码:
//从活动缓存中查找
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
cb.onResourceReady(active, DataSource.MEMORY_CACHE);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
//从内存缓存中查找
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;
}
如代码中所示,loadFromActiveResources是从活动资源中查找所需图片,如果没有则从内存缓存中查找图片;找到图片后通过调用onResourceReady方法,回调给Request,也就是SingleRequest。具体的代码同学们可以自行翻阅去看,你会找到很多之前说过的代码。
如果活动缓存和内存缓存中都没有所需的图片资源,则会创建一个EngineJob和DecodeJob对象。EngineJob没有什么特别的功能,主要负责回调和管理工作,而DecodeJob呢,这个类的注释说的很清楚,负责从缓存数据或原始数据中解码资源,并应用转换和转码的类。DecodeJob实现了Runnable接口,那一定有某个类开启了这个线程,这个类就是EngineJob。
上面说到,EngineJob和DecodeJob对象被创建,之后
engineJob.start(decodeJob);
start方法如下:
public void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
executor.execute(decodeJob);
}
其实就是一个线程池,然后执行了decodeJob这个线程,之后开始执行decodeJob中run方法的内容,进入第四部分
第四部分:
这部分呢,主要分为三块:
(1)从资源缓存(ResourceCacheGenerator)中查找图片,这个缓存是第一篇文章说过的第三个缓存,主要存储解码后的图片资源,找到后层层回调给Request(SingleRequest)
(2)如果资源缓存中没有,则从原始缓存(DataCacheGenerator)中查找图片,这个缓存是第四个缓存,存储的图片是原始数据,基本上都会存在手机的SDCard中
(3)如果上面两个都没有,就是从图片地址(SourceCacheGenerator)中查找(网络就从网络中找,本地的就从本地中找)
以上就是今天的全部内容,看似篇幅不多,但是需要反复的去源码中翻看,只有把源码翻熟翻透,才能明白流程。今天没有代码,下片说完生命周期再统一分享。
欢迎大家提问与纠错!