知识梳理系列之七——Glide的原理
Glide的基本使用
常用的使用方式如下,特点是链式调用,with/load/into是必不可少的,还可以添加图片数据格式、占位图、错误占位图、缓存机制、网络请求等等配置。
Glide.with(Context)
.load(StringUrl)
.into(ImageView);
总而言之,功能十分强大而不需要自己实现图片的加载、数据的转换、缓存等等。
那么他是怎样帮我们把这些都处理完的呢,看下面解析。
Glide源码解析
Glide的三步曲分别做了什么?
1. 第一步Glide.with(Context);
with方法有多个,都是传入Context(Context的子类如:Activity、Fragment,支持support和app包下的两种Fragment,支持FragmentActivity) 或者 View(最终还是通过view获取了Context);
1.1 初探with
源码大同小异,基本都是调用了{@link Glide#getRetriever(Context)}和{@link RequestManagerRetriever#get()}两个方法;
特别注意,这里的返回值是RequestManager对象,后面会用到!!
// Glide.java
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
1.2 getRetriever获取请求管理索引器对象
// Glide.java
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
//... 检查Context不能为空
return Glide.get(context).getRequestManagerRetriever();
}
// 1. volatile 关键字已经在多线程中分析过,用来保证可见性和部分有序性;
private static volatile Glide glide;
// 2. 可以看出Glide的实例是单例的;
@NonNull
public static Glide get(@NonNull Context context) {
if (glide == null) {
// 3. 此方法通过反射创建了一个GeneratedAppGlideModuleImpl的实例
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
// 4. 真正的检查和初始化Glide实例;
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
在上述的源码可以看出:
a. 在获取请求管理索引器对象的过程中,先创建了Glide的实例,并对其进行初始化,Glide是单例的,使用了双重校验锁单例模式;
b. 使用反射,创建了GeneratedAppGlideModuleImpl实例
继续看源码:(这部分可以简略看下或直接看总结)
// Glide.java
private static void checkAndInitializeGlide(
// ... 使用布尔标志判断是否已经初始化
initializeGlide(context, generatedAppGlideModule);
// ...
}
// 1. 终于到核心方法执行初始化操作了, 这期间通过同名方法new了一个GlideBuilder实例
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
...
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
...
// 2. 从清单配置文件中解析出GlideModule列表
manifestModules = new ManifestParser(applicationContext).parse();
...
// 3. 根据是否配置了GlideModule来决定是否需要使用其统一配置的Options,以及统一注册的Componnets
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory()
: null;
builder.setRequestManagerFactory(factory);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
// 4. 最重要的一步!!!
// 使用GlideBuilder构造器类构造出了Glide实例
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
...
module.registerComponents(applicationContext, glide, glide.registry);
...
}
if