本文基于Glide版本:
com.github.bumptech.glide:glide:4.11.0
Glide最常用的一行代码如下,也概括了Glide的初始化、加载图片(本地、缓存、网络图片)、绑定显示的流程。本文就从该行代码开启Glide的源码之旅。
Glide.with(this).load(url).into(mainPic);
1-初始化with()
首先是Glide.with()方法,通过该方法主要是通过RequestManagerRetriever获取一个RequestManager对象。RequestManager是处理图片加载过程的具体实现类,后面详细讲述。
调用链路:(1)Glide.with
–>(2)Glide.getRetriever
–>(3)Glide.get
–>(4)Glide.getRequestManagerRetriever
–>(5)RequestManagerRetriever.get
–>(6)RequestManager
(1)Glide.with
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
(2)Glide.getRetriever获取RequestManagerRetriever
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
//判空检测,判断对象空指针以及Activity/Fragment是否处于活跃状态
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
return Glide.get(context).getRequestManagerRetriever();
}
(3)Glide.get(context)获取Glide的全局单例。这么多逻辑主要是处理用户自定义AppGlideModule的情况。
- 继承AppGlideModule实现自定义Glide,重写网络加载框架、缓存路径、自定义缓存等定制内容,在class前加上@GlideModule注解
- 通过Annotation Processer在编译时根据@GlideModule注解来生成自定义Glide的代理类GeneratedAppGlideModuleImpl
- 通过反射获取代理类的构造方法并实例化返回
- 若APT方法获取失败则尝试从manifest文件中获取自定义GlideModule。manifest配置自定义module是Glide4.0以前的方式,新版本基本都采用注解APT的方式实现。
- 若都没有自定义的module,则通过GliderBuilder的工厂模式生成实例。
public static Glide get(@NonNull Context context) {
if (glide == null) {
//获取自定义AppGlideModule的代理类GeneratedAppGlideModuleImpl
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
(4)Glide.getRequestManagerRetriever获取Glide.get方法中初始化的RequestManagerRetriever对象。
public RequestManagerRetriever getRequestManagerRetriever() {
return requestManagerRetriever;
}
(5)RequestManagerRetriever.get方法根据调用的context及是否主线程返回对应的RequestManager。context为FragmentActivity时调用:
public RequestManager get(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
//Activity、FragmentActivity情况
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
return get((Activity) context);
} else if (context instanceof ContextWrapper
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
//非UI线程情况
return getApplicationManager(context);
}
如果context是Fragment时调用:
public RequestManager get(@NonNull Fragment fragment) {
Preconditions.checkNotNull(
fragment.getContext(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
//非UI线程
if (Util.isOnBackgroundThread()) {
return get(fragment.getContext().getApplicationContext());
} else {
//context为Fragment情况
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());