Glide(4.6.1)
简介
bumptech开发,多款Google应用使用
优点
- 组件生命周期绑定,防止内存泄漏
- 多种原始数据加载(asset,网络,byte[],流),同时支持Volley,Okhttp;默认使用HttpURLConnection实现网络—参见DataFetcher
- 支持gif,可以扩展支持svg,支持视频快照
- 内部多面向接口编程,容易扩展
- 注册进程低内存回调,可以释放内存,降低OOM风险
缺点
整体结构
关键类
- Glide
使用入口 - Engine
加载引擎
调用流程
基本使用
Glide.with(context).load(url).into(ImageView)
以上述使用方式为例,解析整个流程,其中包括RequestManger的获取,资源的获取,解析,和最好的回调设置
涉及的关键类有:
- RequestManager
glide中管理,启动请求的类,可以使用Activity,Fragment来绑定声明周期,自动关联定制,开始,重启请求 - RequestBuilder
通用的请求构建类,可以对所有的资源类型设置参数,开始加载 - RequestTracker
对于完成,失败的请求进行记录,取消,重启(非线程安全,只在主线程中使用) - Target(Interface)
资源加载的目标,并且绑定相关声明周期;如果在内存中,或者通过空的model进行加载时,不会回调onLoadStarted方法,其实现类较多,如常用的ImageViewTarget Request(Interface)
为Target加载资源的请求类,其实现类有:- ErrorRequestCoordinator
- SingleRequest
- ThumbnailRequestCoordinator
Engine
负责启动加载和管理active和cached资源EngineJob
对加载行为进行监听,并在完成时通过Handler进行线程转换DecodeJob
负责解析原始资DataFetcherGenerator(Interface)
根据原始资源的不同,生成对应的DataFetcher,并触发DataFetcher的loadData()方法,其实现类有:- DataCacheGenerator
- ResourceCacheGenerator
- SourceGenerator
DataFetcher(Interface)
将原始资源加载但内存中,实现类加多:- AssetPathFetcher
- HttpUrlFetcher
- OkhttpStreamFetcher
- VolleyStreamFetcher
- …
简单解析
- 整个流程的入口为Glide的with()方法,改方法的参数重载有Context,FragmentActivity,Activity三种,内部通过参数的不同的实例类型(使用不同类型的Lifecycle和RequestManagerTreeNode)获取RequestManager
- 每个RequestManager通过RequestManagerFactory构建,然后使用load方法获取RequestBuilder对象;load方法接收
byte[]
,URL
,Integer(resourceId)
,File
,Uri
,Drawable
,Bitmap
,String
几种参数类型,每个类型的缓存策略不同,如Bitmap
就不需要进行磁盘缓存; - 通过load方法获取RequestBuilder对象后,可以直接通过into()方法,将目标容器可以设置为对应的ImageView,其会转化为ImageViewTarget;into()方法也可以接收Target类型参数(Target接口定义了资源加载的事件回调)
- 最终调用三个参数的into()方法后,由之前的RequestManager对象的track()方法发起Request对象的beigin()方法
以流程图中的SingleRequest为例,在该对象内的onSizeReady()方法中调用Engine的load()方法开始加载流程
- 首先验证是否存在于ActiveResources中,存在则进行回调,流程完毕
- 验证是否在MemoryCache中,此处采用remove()的方式获取资源对象EngineResource<>,存在则进行回调,流程完毕
- 验证是否在请求列表中,存在则添加回调,流程完毕
- 否则通过相关参数构建EngineJob,DecodeJob对象,并调用EngineJob的start()方法开始获取原始资源流程(此处包括本地磁盘和原始数据两层)
- EngineJob内部根据参数选取适合的线程池(GlideExecutor),执行DecodeJob中的run方法(DecodeJob实现了Runnable)
- 根据不同的阶段进行后续操作,会在适合的阶段调用DataFetcherGenertor的startNext()方法,并在该方法中有限获取本地磁盘缓存
- 在startNext()方法中调用DataFetcher中loadData()方法,该方法会读取数据到内存(如网络,磁盘,asset等),并在完成后对结果回调至DecodeJob中
- 后续会涉及到LoadPath,DecodePath,ResourceTranscoder等一系列操作
- 在最后返回Resource后,将该资源缓存到ActiveResources中,在当前正在执行的任务队列中Jobs中移除;将Resource回调至SingleRequest中,最终回调Target的onResourceReady()方法
- 以ImageViewTarget为例,进行资源设置和执行动画
note:流程图中缺少上述9步,分析时略过
注意事项
- 由于Glide.with()内通过使用FragmentManager/SupportFragmentManager操作Fragment实现的生命周期的绑定,所以对调用线程有验证,只有在主线程中调用时才有效,非主线程中调用时会使用ApplicationContext进行操作,并且声明周期无关
- EngineResource的每个对象进行引用计数,在release()中及时释放内存其他引用对象
- 三个缓存容器,按优先级ActiveResources > MemoryCache > LazyDiskCacheProvider
- 在Engine内部包括原始数据(sourceExecutor)和磁盘数据(disCacheExecutor)两种线程池,初始化位于GlideBuidler(还包括一个动画线程池(animationExecutor))中,上述的线程池为glide中的自定义线程池GlideExecutor
- 使用了大量的对象池技术,如GlideBuilder中的BitmapPool、ArrayPool等