在《Glide工作总体执行流程概述》一篇博文中简单分析了glide的工作流程,简而言之就是Glide先构建RequestManager对象,然后RequestManager对象构建ReqeustBuilder对象,再由RequsetBuilder对象创建一个Requset对像,最后将Request交给RequsetMangaer管理,然后RequestManager通知request调用begin发起请求将生成的图片资源交给具体的Target的过程。只不过上篇文章只是简单的做了梳理工作,并没有对详细的说明,本篇就承接上文来继续分析。所以建议读此篇博文的童鞋大致瞅一眼《Glide工作执行流程概述》
本篇还是以SingleRequest为例来说明,在资源还没有加载好的时候,SingleRequest的begin方法会调用一个onSizeReady方法:
public void begin() {
//省略部分代码
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
}
//省略部分代码
}
进入onSizeReady内部翻看一翻,仍然剔除暂时与本文无关的代码:
private Engine engine;
public void onSizeReady(int width, int height) {
//省略部分代码
status = Status.RUNNING;
loadStatus = engine.load(glideContext,model,//url
//省略一大堆参数);
}
也就是说onSizeReady方法内部也就是主要时调用来Engine对象的load方法,那么这个engine对象是什么鬼呢?先看看这个对象是时候初始化的,该对象是在初始化Glide对象的时候进行来初始化,具体的可在GlideBuilder的build方法找到:
public Glide build(Context context) {
//省略本分代码
//如果客户端没有配置自己的Engine
if (engine == null) {
engine = new Engine(memoryCache, diskCacheFactory, diskCacheExecutor, sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor());
}
return new Glide(context,engine,//省略一大堆参数);
}
从Engine类的构造起所需要的参数来看,Engine负责内存缓存,磁盘缓存等等管理工作,这些内存和磁盘缓存等相关的类可以通过Builder模式让客户端自己构建自己的缓存逻辑,这也是Builder模式的强大之处,该模式也算是常用的设计模式之一,其设计理念还是很值得借鉴的,到此为止Engine的初始化已经创建完毕。下面继续沿着SingleRequest的流程分析engine.load方法:
//返回一个LoadStatus对象
public LoadStatus load(//一大堆参数) {
//1、生成一个EngineKey对象
EngineKey key = keyFactory.buildKey(model,//url
signature, width, height, transformations,
resourceClass,
transcodeClass, //Drawable.class
options);
//2、从缓存加载图片资源
EngineResource job = (EngineJob) message.obj;
switch (message.what) {
case MSG_COMPLETE:
job.handleResultOnMainThread();
break;
}
return true;
}
仅仅是调用了EngineJob的handleResultOnMainThread方法,此时我们已经将图片数据切换到了UI线程:
void handleResultOnMainThread() {
//省略部分代码
//将数据转换成engineResource
engineResource = engineResourceFactory.build(resource, isCacheable);
hasResource = true;
//省略部分代码
for (ResourceCallback cb : cbs) {
if (!isInIgnoredCallbacks(cb)) {
//特么的第四个callback
cb.onResourceReady(engineResource, dataSource);
}
}
}
该方法做了两件事: 1、将resource交给engineResource来持有 2、将engineResource交给本文的**第四个callback
**
那么这第四个callback又是什么?是ResourceCallback接口,该接口是通过初始化EngineJob的时候调用EngineJob的 addCallback(ResourceCallback cb)方法传进来的。且EngineJob 的初始化是在Engine的load 方法中,而load 的方法的一个参数就是又这个callback, 且load的调用又是在文章开头的SingleReqeust方法,顺藤摸瓜发现第四个callback就是SingleReqeust,所以我们进入该SingleReqeust的onResourceReady方法:
public void onResourceReady(Resource resource, DataSource dataSource) {
//调用重载方法:
onResourceReady((Resource) resource, (R) received, dataSource);
}
private void onResourceReady(Resource resource, R result, DataSource dataSource) {
this.resource = resource;
//最终调用target的onResourceReady
target.onResourceReady(result, animation);
}
如果你读过博主的《Glide工作总体执行流程概述》这篇文章的话,就可以知道此处的target就是DrawableImageViewTarget,该target的onResourceReady方法的最总逻辑就是调用:
imageView.setImageDrawable(resource);
来完成图片的展示。
到此为止,本篇分析完毕,分析源码的过程中四个callback来回调度可把我绕坏了,为了本篇博文的主题连续性,基本上省略了好多东西没讲,什么ModelLoader啦,LoadData啦,Fetcher啦,将在后续博文中讲解,敬请期待,如有不当之处,欢迎批评指正