Glide源码分析(四),DecodeJob执行过程

开始本文之前,DecodeJob它实现了Runnable接口,敏感的朋友可能已经意识到,加载代码的入口就在这里,会在一个新的线程中去加载资源。DecodeJob这个类的代码非常多,主要有以下几个重要的点。

  1. 封装一些从上面传过来的参数信息,不知道是否还有印象,我们的glide大部分信息是通过前面RequestBuilder中得到的。这里,它内部构造了一个DecodeHelper类,封装了大部分的请求信息。

  2. 数据加载模块DataFetcher与ModelLoader,以及加载数据的回调接口。详细参考数据加载DataFetcher与ModelLoader结构。DataFetcher中定义了加载数据的接口,其子类很多,比如从网络加载或者是文件加载,均是由其子类具体实现。

  3. DataFetcherGenerator使用已注册的{@link com.bumptech.glide.load.model.ModelLoader ModelLoaders}和一个模型生成一系列{@link com.bumptech.glide.load.data.DataFetcher DataFetchers}。在DataFetcherGenerator中,通过DecodeHelper类,我们还可以拿到ModelLoader的信息,而通过ModelLoader我们可以得到LoadData的数据结构,从而取得对应的DataFetcher,进而去获取数据。DataFetcherGenerator结构

DecodeJob其他详细信息可以参考DecodeJob结构
加载一个资源最终到一个ImageView上面的大致流程图如下:

sequence_engine.png
  1. SingleRequest的onSizeReady方法启动Engine的load方法,同时将ResourceCallback传入。这个ResourceCallback最终会调用相关的Target,完成资源的最终渲染。
  2. Engine的load方法,它里面会根据条件判断,这里我们讨论是本地完全没有缓存的情况,这个时候,load中,会创建EngineJob与DecodeJob,DecodeJob是真正开启线程加载数据的地方,EngineJob负责调度DecodeJob以及和上层模块通信,它们是一个一对一的关系。EngineJob中实现了DecodeJob.Callback用于监听下面数据加载的状态,同时在EngineJon中维护了一系列的从Engine#load方法中传入的ResourceCallback信息,用户在监听到数据加载结果之后,通知上层模块,也就是SingleRequest。随之触发启动DecodeJob,开始任务。
  3. DecodeJob的run方法得到执行,在run方法里,它会构造一个DataFetcherGenerator,run方法里面会触发DataFetcherGenerator的startNext方法,同时通过设置到DataFetcherGenerator的FetcherReadyCallback接口,监听数据的获取状态,再将结果上报至EngineJob中(它实现了DecodeJob.Callback接口)。
  4. DataFetcherGenerator的startNext,generator会从DecodeHelper中去获取当前的ModelLoader信息,构造出一个LoadData结构类型的数据,得到相应的DataFetcher对象。DataFetcherGenerator子类实现了DataFetcher.DataCallback接口。它是用于监听DataFetcher#loadData结果。
  5. DataFetcher#loadData完成之后,会将执行结果上报至
    DataFetcherGenerator,因为其实现了DataFetcher.DataCallback接口,在其实现上面,回继续回调其成员变量执行的FetcherReadyCallback中的方法,而此时,FetcherReadyCallback实现类正是DecodeJob,因此,代码继续执行到DecodeJob的回调方法中,我们先至考虑简单的情况,忽略线程之间的切换。
  6. 回到DecodeJob的FetcherReadyCallback的实现中,它接下来会继续回调设置在其成员变量的类型为DecodeJob.Callback引用,而正是EngineJob实现了这个Callback,因此,代码流程进一步转换给到EngineJob中。
  7. EngineJob实现了DecodeJob.Callback,此时还没有做线程切换,是处于和DecodeJob#run方法相同的线程,此时,EngineJob中利用Handler机制,将继续分发加载到的数据的结果,触发其handleResultOnMainThread方法。见名思义,此时已经切换到了主线程。
  8. EngineJob#handleResultOnMainThread方法中,会回调在上面讲到的,它中维护了一系列的从Engine#load方法中传入的ResourceCallback信息,所以这里会对它们继续进行回调。
  9. ResourceCallback,它的实现是在SingleRequest中,在它的实现中,会将结果交给相应的Target去处理,而我们的ImageView渲染资源正是由这些Target在调度。所以,最终资源就成功的显示到了控件上面。

总体来说,宏观上代码逻辑还是很清晰的,一次加载过程,会创建一个SingleRequest,调用全局的加载引擎Engine,去创建一对EngineJob与DecodeJob,最后在DecodeJob中,根据DataFetcherGenerator获取到相应的DataFetcher,执行数据的加载。成功之后,一步步回调回去。先是DataFetcher到DataFetcherGenerator,再是DataFetcherGenerator到DecodeJob,再是从DecodeJob到EngineJob,进而在EngineJob中做线程切换,回到主线程,将结果回调至SingeRequest,再由SingleRequest中保存的Target引用通知到对应的控件,完成资源的渲染。同时EngineJob也会告知Engine,此次job已经加载完成,是由EngineJobListener完成的。大致就是一个链式的Callback回调过程。后面我会在代码上,根据这个大纲,详细分析一次从网络加载,并缓存到磁盘的详细过程。

下一篇 Glide源码分析(五),EngineJob与DecodeJob代码详细加载过程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容