Glide是BumpTech开发的一个同时可支持图片、GIF以及视频加载的Android开源库,同时Glide支持任何用户自定义的网络栈,其主要有以下几个特点:
- 支持GIF格式动画的解码;
- 支持本地视频加载解码;
- 加载大图之前,可预先加载一个小图片
- 自动管理资源加载请求的生命周期;
- 给定图片尺寸,可以对资源进行自由转换
这里就来分析下Glide的具体架构以及介绍其主要特点,分如下几个方面:
- Glide代码架构及工作原理;
- Glide如何自动管理资源加载请求的生命周期的?
- Glide是如何进行图片的加载与转换的?
架构及工作原理
先来看一下Glide的代码结构,这里主要看下几个核心的包:
com.bumptech.glide: 主要负责Glide的初始化,参数配置,Request的创建;com.bumptech.glide.load: 主要负责资源的加载,解码与格式转换;com.bumptech.glide.manager: 负责Glide请求生命周期的自动管理;com.bumptech.glide.module: 用于加载解析用户自定义的网络模块;com.bumptech.glide.provider: 管理Glide中图片、GIF等资源的加载与转换器;com.bumptech.glide.request: 资源加载请求相关以及动画;com.bumptech.glide.util: 常用工具类;
下图是Glide的原理简图。可以看到,Glide大致可以分为五个部分:
Glide: 初始化系统,负责管理系统其他模块如数据加载器、网络栈等初始化管理;RequestManager: 创建、初始化以及管理系统所有的Request;Engine: 将资源加载请求放入执行线程池,加载完后返回给主线程;ExecutorService: 线程池执行服务,负责分发调度EngineRunnable可执行对象;DataFetcher: 从磁盘或者网络端加载数据
关于Glide资源加载的详细过程请参考我的另一篇文章:Glide图片加载过程分析
接下来就来看一看,Glide的两个特征:请求生命周期的自动化管理以及系统的泛型化。
** 如何自动进行生命周期管理**
Glide从3.0开始支持Request生命周期的自动管理,即随着Activity或者Fragment的生命周期自动启动、恢复或者停止Request。Glide提供了两种生命周期管理策略:ApplicationLifecycle和ActivityFragmentLifecycle,前者确保Request的生命周期与APP的Application的生命周期保持一致;而后者则使Request的生命周期与Activity或者Fragment保持一致。
那么,ActivityFragmentLifecycle是如何实现的?
1 |
|
在初始化RequestManager时,会根据传入的Context来构造RequestManager(这里假定这里是一个FragmentActivity):
1 |
|
生成一个无UI的SupportRequestManagerFragment,并将其中的ActivityFragmentLifecycle作为构造函数的参数传递给RequestManager:
1 |
|
在RequestManager构造时,会将RequestManager作为上述Fragment生命周期的监听者,从而使得RequsetManager中的Request生命周期始终与Fragment保持一致:
1 |
|
这样,不难看出这样一个生命周期事件的通知链:
1 |
|
系统的泛型化
Glide在设计上尽可能保持抽象与泛型化,从最大程度上保持了系统的可扩展性与可维护性。这些泛型化主要体现在如下几个方面:
- 用户加载资源的来源可能是一个包含了URI路径的字符串,可能是一个文件,可能是一个URL,因此需要对资源加载的类型泛型化成一个类
ModelLoader<T,Y>(称之为ModelType); - 资源的数据类型可能是
InputStream,也可以是字节流数组byte[],还可以是一个文件File,因此需要对数据类型进行泛型化成一个类DataFetcher<Y>(称之为DataType); - 加载完的资源类型可能是一个
drawable,也可能是一个gif文件;可能是一个bitmap,也可能是一个byte[]字节数组,同样将其泛型化成一个类Resource<Z>(称之为ResourceType,实际上是对加载完后的资源的一个包装类型); - 不同资源类型可能需要进行转换,比如讲
bitmap转换成字节数组byte[];将drawable变换成bitmap,因此可以将这种转换的关系泛化成一个类ResourceTranscoder<Z,R>(TranscodeType);
接下来就来看下这几个泛型类的实现。
ModelLoader
ModelLoader的功能是将资源加载到一个具体的数据类型,比如InputStream中,实际是利用DataFetcher来实现资源的加载。Glide提供了多种类型的ModelLoader将不同资源的文件加载到一个InputStream中去:
HttpUrlGlideUrlLoader:将一个GlideUrl加载后到一个Inpustream中;StreamByteArrayLoader: 将一个字节流加载到一个InputStream;StreamFileLoader: 将文件加载到一个InputStream;StreamUrlLoader: 将一个URL资源加载到InputStream;StreamResourceLoader:讲一个Android资源文件加载到InputStream;
DataFetcher
DataFetcher用于从文件或者网络上加载资源,将其变成一个特定的数据类型:
HttpUrlFetcher: 获取一个URL资源的InputStream;ByteArrayFetcher: 将一个字节流数据变成InputStream输入流;StreamLocalUriFetcher: 获取本地URI资源的InputStream;
1 |
|
ResourceTranscoder
将一种资源类型Resource<Z>转换成另一种类型Resource<R>,比如Bitmap转换成Drawable:
BitmapBytesTranscoder: 将bitmap转码成一个字节数组;BitmapToGlideDrawableTranscoder: 将一个bitmap转码成一个GlideDrawable;GifDrawableBytesTranscoder: 将GIF文件转码成字节数组;
有关Glide加载图片的过程以及泛型参数的擦除请参考另一篇文章Glide图片加载过程分析 。
Glide源码地址
- Glide源码地址:https://github.com/bumptech/glide