问题
Glide加载流程?
Glide整体架构?
Glide数据加载的来源?
Glide缓存加载的流程?
Glide线程切换原理?
Glide如何感知Activity?
Glide哪种情况会返回应用级的RequestManager?
…
带着一些问题去阅读…
使用示例
本篇主要基于glide:4.12.0进行分析。下面是Glide主要的使用示例。
repositories { google()mavenCentral()
}dependencies { implementation 'com.github.bumptech.glide:glide:4.12.0'annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
}
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
可以看到,Glide的加载主要分三步:with()
、load()
、into()
。理解了这三步Glide做了什么,基本就理解了Glide源码加载图片的大体逻辑和框架了。
with()
Glide的with()
方法的目的是根据不同的上下文context
获得RequestManager
对象。
RequestManager
对象解释:A class for managing and starting requests for Glide.
下面开始详细分析。
首先看Glide中with()
方法所有的重载函数:
RequestManager with(Context context)
RequestManager with(android.app.Activity)
RequestManager with(androidx.fragment.app.Fragment)
RequestManager with(androidx.fragment.app.FragmentActivity)
RequestManager with(View view)
以Glide中的 with(android.app.Activity)
为例:
public static RequestManager with(@NonNull FragmentActivity activity) {return getRetriever(activity).get(activity);}
可以看到,RequestManager
由getRetriever(activity).get(activity)
得到,因此有两个问题:
1 getRetriever(activity)
获得什么对象?
2 这个对象的get()
获得什么?
首先看第一个问题,看getRetriever(activity)
:
private static RequestManagerRetriever getRetriever(@Nullable Context context) {...return Glide.get(context).getRequestManagerRetriever();}
getRetriever(activity)
获得了RequestManagerRetriever
对象。
接下来进RequestManagerRetriever
对象看它的get()
实现,它根据with()
重载方法参数的不同进行不同重载:
RequestManager get(Context context)
RequestManager get(android.app.Activity)
RequestManager get(androidx.fragment.app.Fragment)
RequestManager get(androidx.fragment.app.FragmentActivity)
RequestManager get(View view)
以其中一个为例:
public RequestManager get(@NonNull FragmentActivity activity) {if (Util.isOnBackgroundThread()) {return get(activity.getApplicationContext());} else {assertNotDestroyed(activity);frameWaiter.registerSelf(activity);FragmentManager fm = activity.getSupportFragmentManager();return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));}}
可以看到,RequestManager
返回两种类型,分别是当是子线程时的get(activity.getApplicationContext());
和其他的supportFragmentGet()
。
首先看with()
在子线程中统一返回的应用级别RequestManager
单例,看 get(activity.getApplicationContext());
:
@NonNullpublic RequestManager get(@NonNull Context context) {...if (context instanceof FragmentActivity) {return get((FragmentActivity) context);...}
继续追这个get()
方法的具体实现:
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)) {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());}}return getApplicationManager(context);}
看到这一行:if (Util.isOnMainThread() && !(context instanceof Application))
,这行判断不仅决定了子线程中直接返回getApplicationManager(context)
方法,而且当这个传入的context是Application时,也返回全局的getApplicationManager(context)
方法获得的应用级别RequestManager
。
继续追这个getApplicationManager(context)
方法的具体实现:
@NonNullprivate RequestManager getApplicationManager(@NonNull Context context) {if (applicationManager == null) {synchronized (this) {if (applicationManager == null) {Glide glide = Glide.get(context.getApplicationContext());applicationManager =factory.build(...);}}}return applicationManager;}
至此我们知道了with()
返回是应用级别RequestManager
单例:applicationManager的两种情况:子线程+context=Application
那么不是子线程时的supportFragmentGet()
呢,这种情况又是如何生成的RequestManager
?我们具体看下RequestManagerRetriever.supportFragmentGet()
:
private RequestManager supportFragmentGet(@NonNull Context context,@NonNull FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {//获取空fragment,无则创建SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);// 让fragment持有RequestManagerRequestManager requestManager = current.getRequestManager();if (requestManager == null) {//如果空fragment没有RequestManager,就创建一个Glide glide = Glide.get(context);requestManager =factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);...//让空fragment持有RequestManagercurrent.setRequestManager(requestManager);}//返回页面级别的RequestManagerreturn requestManager;}
继续看这个新fragment怎么创建的:
private SupportRequestManagerFragment getSupportRequestManagerFragment(@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {//通过tag找到Activity中的空fragmentSupportRequestManagerFragment current =(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);if (current == null) {//findFragmentByTag没找到空fragment,有可能是延迟问题?再从Map中找一下current = pendingSupportRequestManagerFragments.get(fm);if (current == null) {//确实没有空fragment,就创建一个current = new SupportRequestManagerFragment();current.setParentFragmentHint(parentHint);//缓存进MappendingSupportRequestManagerFragments.put(fm, current);//空fragment添加到Activity,使其能感知Activity的生命周期fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();}}