「Glide」源码解析系列
承前启后
Engine将要加载的资源在引用缓存和内存缓存中均未命中,重任就交到了Job身上。
这节就来看看有几种Job,他们的功能是什么!
此节涉及到的类有
EngineJob
GlideExecutor
DecodeJob
Job流程
这是Engine.load方法中,Job逻辑调用相关的代码
梳理流程:
- 创建了engineJob和decodeJob对象,且engineJob为decodeJob的参数;
- key与engineJob的关联,并存储在jobs中
- 给engineJob加监听
- engineJob启动decodeJob
能够看出engineJob和decodeJob并不是同一级,engineJob调用decodeJob使其工作,然后engineJob将工作状态回调到SingleRequest。(挖了这么深,终于触底反弹了)
EngineJob
先来看看EngineJob对象的产生
Pools.Pool的用法在「Glide」请求的生成一节中有介绍
这里通过pool复用EngineJob对象,通过init方法重置参数
这是EngineJob的构造参数,有没有注意到Executor,是不是眼前一亮【线程池】
线程相关内容可以看以下Android中的线程问题回忆下。
EngineJob的Executor来自EngineJobFactory
EngineJobFactory的Executor来自Engine
Engine来自GlideBuilder,这也是为什么在「Glide」中的Engine一篇中花篇幅讲Engine的起源(早期的伏笔)
看到,所有的Executor来自GlideExecutor
GlideExecutor
以newSourceExecutor为例
计算最优线程数
注意红蓝框的区别
先生成ThreadPoolExecutor对象,作为参数生成GlideExecutor
重点:GlideExecutor采用了静态代理模式,外部将任务交到GlideExecutor执行,但实际的执行者是ThreadPoolExecutor,优点是统一了Glide中所有的Executor为GlideExecutor,达到了高内聚的目的
不清楚的可阅读常见设计模式总结
我们知道线程池ThreadPoolExecutor的区别在于参数
重点看看DefaultThreadFactory
DefaultThreadFactory对象在初始化时传入了一个布尔值变量preventNetworkOperations译为阻止网络操作
这里是生成SourceExecutor传入的值为false,不进入if逻辑
而DiskCacheExecutor传入的是true
preventNetworkOperations参数的作用是什么
if逻辑内设置了StrictMode,不清楚的可以参考这篇文章StrictMode机制以及使用场景
效果是:有网络请求,杀死此线程
这下再回去看看传入的布尔值,
从DiskCache中加载资源执行的线程,禁止网络请求
从源加载资源执行的线程,允许网络请求
这是GlideExecutor中即重要有容易忽略的点
DecodeJob
有了EngineJob对象,也知道了其内部Executor的异同来看看DecodeJob
与EngineJob生成对象相同的手法:复用对象、重置参数
注意到DecodeJob实现了Runnable接口,而EngineJob内有Executor
果不其然,DecodeJob对象被放到了EngineJob中Executor执行了
中途Executor的选择跳过。。。
来到DecodeJob的run
Run
通过变量runReason选择性的进入分支
stage记录目前执行阶段,currentGenerator记录目前Generator
runGenerators方法推进stage和currentGenerator的变化,进入下一阶段
在runGenerators中while一直在推进stage和currentGenerator向下一阶段变化
各级缓存和源的处理都在其中
总结
Engine只是个状态观察者,实际还要回调到SingleRequest对象
实际的工作由DecodeJob做,而EngineJob负责分配DecodeJob工作所处的线程
作者:s1991721
链接:https://www.jianshu.com/p/5170ac35cae6
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
来源:oschina
链接:https://my.oschina.net/u/4000302/blog/3159889