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