Glide 4.0+源码分析
-
-
- 总体分析
- 图片加载流程
-
- with
- load
- into
-
- into
- buildRequest
- buildThumbnailRequestRecursive
- obtainRequest
- begin
- onSizeReady
- load
- DecodeJob.run()
- runWrapped
- getNextStage & getNextGenerator
- runGenerators
- SourceGenerator.startNext()
- loadData
- onResponse
- onDataReady
- SourceGenerator.startNext
- DataCacheGenerator.startNext
- decodeFromRetrievedData
- notifyEncodeAndRelease
- EngineJob.onResourceReady
- EngineJob.notifyCallbacksOfResult
- CallResourceReady
- SingleRequest.onResourceReady
- DrawableImageViewTarget.setResource
- 总结
-
写过Glide的使用和一些注意事项了,这次简单分析下Glide的加载图片流程。
GlideApp.with(context)
.load(resId)
.into(imageView);
总体分析
整体框架可以看作以下几个部分:
- Glide 初始化系统,负责管理系统其他模块,比如:数据加载器、网络栈等。
- RequestManager 创建、初始化以及管理系统所有的Request。
- Engine 将资源加载请求放入执行线程池,加载完后返回主线程
- DataFetcher 从磁盘或者网络端加载数据
按照包的分类如下:

图片加载流程
还是从简单的加载图片开始:
String url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png";
GlideApp.with(context.getApplicationContext())
.load(url)
.into(imageView);
with
会走到Glide里面的with方法
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
会执行getRetriever(context).get(context)返回一个RequestManager对象。它是一个请求管理类。接着看getRetriever方法。
还有很多重载方法,对应各种上下文:
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
@NonNull
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
/** @deprecated */
@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
@NonNull
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
getRetriever
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
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();
}
有判空的处理,为null会判处异常,平时也会遇到的。然后调用Glide的get方法:
Glide.get()
private static volatile Glide glide;
public static Glide get(@NonNull Context context) {
//很明显的单例模式
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
单例模式
很明显是一个单例,这个是DCL+volatile 单例,很严谨的单例。后面会走到一个initializeGlide方法来创建glide的实例。
initializeGlide
构建者模式
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
//拿到application上下文
Context applicationContext = context.getApplicationContext();
//getAnnotationGeneratedGlideModules 是反射创建了GeneratedAppGlideModuleImpl类
//GeneratedAppGlideModuleImpl 是注解生成的类,4.0+版本特性,主要创建GeneratedRequestManagerFactory的工厂类
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
//清单文件的配置项,可以跳过
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
if (annotationGeneratedModule != null
&& !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
Set<Class<?>> excludedModuleClasses =
annotationGeneratedModule.getExcludedModuleClasses();
Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
while (iterator.hasNext()) {
com.bumptech.glide.module.GlideModule current = iterator.next();
if (!excludedModuleClasses.contains(current.getClass())) {
continue;
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
}
iterator.remove();
}
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
}
}
//以上是清单文件的配置项,可以跳过
//创建请求管理的工厂类,就是前面提到的GeneratedAppGlideModuleImpl 会调用new GeneratedRequestManagerFactory()创建
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);
}
//构建参数 应用上下文 构建单例,也会创建RequestManagerRetriever实例,还会执行一些任务,还会创建engine类。先跳过
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.registerComponents(applicationContext, glide, glide.registry);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
//Glide实现了ComponentCallbacks2接口,实现了trimMemory接口,会根据内存被使用情况,清除一些缓存。
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
主要做了几个操作:获取注解生成的类、创建请求工厂类RequestManagerFactory、获取清单文件的配置信息、添加ComponentCallbacks2接口监听处理内存,最后生成Glide实例。
RequestManagerRetriever.get()
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
在返回return Glide.get(context).getRequestManagerRetriever()这句代码中,getRequestManagerRetriever就会返回RequestManagerRetriever对象,在联级调用RequestManagerRetriever.get()方法。
由于with()有很多重载方法,具体只看Application、activity和fragment的处理逻辑。
Application
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
if (this.applicationManager == null) {
synchronized(this) {
if (this.applicationManager == null) {
//获取前面创建的单例glide
Glide glide = Glide.get(context.getApplicationContext());
//获取build构建的RequestManagerFactory工厂类创建RequestManager。
this.applicationManager = this.factory.build(glide, new ApplicationLifecycle(), new EmptyRequestManagerTreeNode(), context.getApplicationContext());
}
}
}
return this.applicationManager;
}
工厂模式
这里就是用前面初始化方法创建的factory来创建一个RequestManager。
Activity
现在都是继承AppCompatActivity,而AppCompatActivity再继承FragmentActivity的,所以Activity另一个重载不在推荐了。
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
走的supportFragmentGet,跟下面supportFragmentGet一起看。因为自身是activity,传的是父级FragmentManager。isActivityVisible就是返回当前activity是否finish。
Fragment
@NonNull
public RequestManager get(@NonNull Fragment fragment) {
Preconditions.checkNotNull(fragment.getActivity(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
}
}
走的supportFragmentGet,因为自身是fragment,传的是子级FragmentManager。
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
观察者模式
ActivityFragmentLifecycle有一个LifecycleListener的Set集合。相当于一个被观察者维护了一个观察者的集合。
看getSupportRequestManagerFragment()方法,这里跟glide加载图片的生命周期有关。而SupportRequestManagerFragment的生命周期会与传入的lifecycle进行绑定的,
然后也是调用factory去创建RequestManager。
@NonNull
private RequestManager supportFragmentGet(@NonNull Context context, @NonNull androidx.fragment.app.FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
//去创建一个fragment 用来绑定生命周期
SupportRequestManagerFragment current = this.getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
//获取当前创建的fragment所持有的RequestManager
RequestManager requestManager = current.getRequestManager();
//为null就创建一个
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager = this.factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
RequestManager
RequestManager(
Glide glide,
//与页面生命周期绑定的lifecycle对象
Lifecycle lifecycle,
//提供基于当前上下文对RequestManager的relatives的访问。上下文层次结构是通过嵌套在Activity和Fragments中提供的;应用程序上下文不*提供对任何其他RequestManager的分层访问
RequestManagerTreeNode treeNode,
//请求追踪类
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
//会执行自身的onStart方法
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
//添加连接监视器
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
//添加注册监听
glide.registerRequestManager(this

本文详细解析了Glide 4.0图片加载流程,包括Glide的初始化、RequestManager的创建与管理,以及加载、缓存、网络请求和资源展示的关键步骤。
最低0.47元/天 解锁文章
1925

被折叠的 条评论
为什么被折叠?



