Glide是一个很优秀的图片加载开源框架,它能做到一行代码就可以让图片资源显示出来,对使用者非常友好。对于这么优秀的一款开源库,有很多值得学习和借鉴的地方。这也是为什么已经有那么多关于Glide的文章,自己还要去研究它。这将是一个系列的文章,这属于第一篇,在这篇文章中主要介绍Glide的基本使用以及Glide对象的初始化。当然最重要的事,在这个过程中我们能学到什么,那么我们开始吧
Glide 基本使用
想必使用过Glide的人都会它很容易上手,对于一般的需求,只要一行代码就可以搞定。使用Glide加载图片分为两种方式:一,直接使用Glide对象;二,定义一个继承GlideAppModule(在Application应用中,如果在lib库中则继承LibraryGlideModule)的类,使用GlideModule注解这个类,然后使用GlideApp对象。
使用Glide对象
Glide.with(fragment)
.load(myUrl)
.placeholder(placeholder)
.into(imageView);
使用GlideApp对象
@com.bumptech.glide.annotation.GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
super.applyOptions(context, builder);
}
}
GlideApp.with(fragment)
.load(myUrl)
.placeholder(placeholder)
.fitCenter()
.into(imageView);
GlideApp是Glide生成的类,它的包名与被GlideModule注解的类的包名相同。既然两种方式都可以加载图片,那两种方式有什么区别呢?采用注解的方式可以设置默认的配置,另外还可以自定义扩展新的功能,有关GlideApp的方式可参考《Generated API》
我们能从中学到什么
在了解Glide使用方法后,想象一下如果你也在做某个功能库,该如何设计对外提供的接口呢,我觉得Glide就是一个很好的参考。
- 对于基本功能,接口定义要是设计得简单,让使用者开箱即用。
- 对于复杂功能,要提供配置和扩展,以满足更多的应用场景。
Glide对象创建
在了解Glide的使用后,我们再看下Glide对象创建过程。我们以’Glide.with(activity).load(uri).into(imageView)'为例,Glide对象初始化发生在Glide.with()方法调用过程,我们直接看代码
@NonNull
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
‘with()’ 方法返回的是RequestManager对象,而Glide对象的初始化是在’getRetriever()'方法调用过程中完成的,整个过程如下时序图所示:
时序图中看起来流程比较复杂,实际上比较简单,整个过程分为两步:创建Glide对象和创建RequestManager对象。我们更需要关注的是GlideBuidler.build()过程,这个过程中主要做了一下几件事
- 创建Executor、MemorySizeCalculator、ConnectivityMonityFactory、Bitmap对象池等;
- 创建Engine对象
- 创建Glide对象
我们看下整个过程的几个重要方法,首先是Glide.get()方法
//Glide.java
public static Glide get(@NonNull Context context) {
//glide变量定义为static volatile,然后采用double check的方式实现单例
if (glide == null) {
//annotationGeneratedModule即使用GlideModule注解后,生成的GeneratedAppGlideModuleImpl对象;
//如果没有使用GlideModule注解的方式,那么annotationGeneratedModule为null
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
方法很简单,代码中也有部分说明,Glide采用了单例模式创建对象,而单例的实现方式是double check;这个地方有一点需要注意的是,glide变量必须用关键词volatile修饰,这样可以保证glide对象的修改在线程间是可见的。接着看另一个方法——initializeGlide()
//Glide.java
@GuardedBy("Glide.class")
@SuppressWarnings("deprecation")
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
Context applicationContext = context.getApplicationContext();
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
//Glide.with()的方式,annotationGeneratedModule为null,如果没有在AndroidManifest.xml中配置
//<meta-data
// android:name="com.xxx.xxx.XXXGlideModule"
// android:value="GlideModule" />
//manifestModules是一个空列表。
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
if (annotationGeneratedModule != null
&& !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {