聲明:我目前分析的源碼是最新的Glide源碼:4.12.0版本
implementation 'com.github.bumptech.glide:glide:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
1. Glide簡介
Glide是一個支持拉取,解碼和展示視頻快照,圖片,和GIF動畫的框架,正如它的名字翻譯一樣:滑翔。讓用戶加載任何形式的圖片列表盡可能地變得更快、更平滑。
Glide 使用簡明靈活的流式語法API,允許你在大部分情況下一行代碼搞定需求:
Glide.with(fragment)
.load(url)
.into(imageView);
默認情況下,Glide使用的是一個定制化的基于HttpUrlConnection的棧,但同時也提供了與Google Volley和Square OkHttp快速集成的工具庫。
2. 性能
Glide 充分考慮了Android圖片加載性能的兩個關鍵方面:
圖片解碼速度
解碼圖片帶來的資源壓力
為了讓用戶擁有良好的App使用體驗,圖片不僅要快速加載,而且還不能因為過多的主線程I/O或頻繁的垃圾回收導致頁面的閃爍和抖動現(xiàn)象。Glide使用了多個步驟來確保在Android上加載圖片盡可能的快速和平滑:
- 自動、智能地下采樣(
downsampling)和緩存(caching),以最小化存儲開銷和解碼次數(shù); - 積極的資源重用,例如字節(jié)數(shù)組和Bitmap,以最小化昂貴的垃圾回收和堆碎片影響;
- 深度的生命周期集成,以確保僅優(yōu)先處理活躍的Fragment和Activity的請求,并有利于應用在必要時釋放資源以避免在后臺時被殺掉。
3. 源碼分析
關于Glide的詳細使用介紹,參見前面鏈接即可,但是分析源碼也要有個開始吧,那我們就從最基本的用法入手,Glide最基本的用法就是三段論:with、load和into。那我們現(xiàn)在就先從with開始。
3.1 生命周期的作用域(1.Application, 2.Activity, 3.Fragment)
//com.bumptech.glide.Glide.java
public static RequestManager with(@NonNull Context context) {
// getRetriever(context)返回RequestManagerRetriever,下面的生命周期關聯(lián)會用到
return getRetriever(context).get(context);
}
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getContext()).get(fragment);
}
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
從Glide.with()靜態(tài)方法中,我們可以看到方法可以傳入5個參數(shù):Context、Activity、FragmentActivity、Fragment或者View。按照作用域分,我們可以把它分成兩類:Application類和非Application類。
- Application類:它的生命周期是全局的,沒有空白Fragment就綁定Activity/Fragment。
- 非Application類,它的生命周期跟隨Activity和Fragment的生命周期,專門有一個空白Fragment綁定Activity/Fragment。
從上面with的重載方法看出都會調(diào)用到getRetriever()方法,他其實最終就是返回RequestManagerRetriever對象,緊接著,我們看看RequestManagerRetriever的get方法。這里先分兩個來看:
- Activity、FragmentActivity、Fragment和View
- Context
3.1.1 Activity類的get()
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
//如果不是UI線程,生命周期劃分到Application
return get(activity.getApplicationContext());
} else if (activity instanceof FragmentActivity) {
return get((FragmentActivity) activity);
} else {
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
// 不管是Activity、FragmentActivity、Fragment和View的get(),最終都會調(diào)用到fragmentGet()
return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
//最終with返回綁定了代理Fragemnt的RequestManager
private RequestManager fragmentGet(
@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//創(chuàng)建一個沒有UI的空Fragment來監(jiān)控用戶自定義的Activity生命周期
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
//創(chuàng)建Glide實例
Glide glide = Glide.get(context);
//綁定Glide和空白的Fragemnt
//注意?。?這里創(chuàng)建RequestManager的時候會傳入Lifecycle,后面會根據(jù)這個lifecycle來透傳fragment的生命周期給Glide
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}
3.1.2 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)) {
// 如果在UI線程,并且是3.1.1小節(jié)的組件,就調(diào)用Activity類的get(),返回綁定了空Fragment的requestManager
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());
}
}
// 作用域是Application返回的返回綁定了空Fragment的requestManager
return getApplicationManager(context);
}
private RequestManager getApplicationManager(@NonNull Context context) {
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
//生命周期和Application一致
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
3.1.3 小結
Glide的with()生命周期總結如下圖

- 子線程中Glide調(diào)用get()、傳入ApplicationContext和ServiceContext,對應的生命周期屬于Application域,生命周期和Application一致
- Activity、Fragment和View對應的生命周期是被代理Fragemnt監(jiān)控的,Glide內(nèi)部邏輯會根據(jù)Activity的生命周期做相應調(diào)整
3.2 Glide生命周期感知過程
如3.1.1小節(jié)中分析的,不管with傳入的是fragment、Activity還是View,RequestManagerRetriever都會創(chuàng)建一個沒有UI的Fragment(SupportRequestManagerFragment)來當代理,當用戶自定義的Activity或者Fragment生命周期發(fā)生變化的時候,Glide內(nèi)部可以通過代理Fragment知道生命周期發(fā)生的變化,因此內(nèi)部也做相應的處理。例如下載并且加載是一個比較耗時操作,如果下載完成之后,Activity已經(jīng)被銷毀了,那就不用加載了,所有這就是Glide感知組件生命周期的意義,用戶不用主動調(diào)用clear()方法來釋放資源了。關聯(lián)關系如下圖。

3.3 Glide與空Fragment綁定過程
從3.1.3小結中可以知道,只有在主線程中調(diào)用with()并且傳入Activity或者Fragment會綁定空Fragment。當傳入的activity,這個activity上覆蓋的空Fragment是RequestManagerFragment;當傳入的是fragment,覆蓋在上面的空fragment是SupportRequestManagerFragment。邏輯都是一樣的,下面以傳入fragment來分析。
/** Pending adds for SupportRequestManagerFragments.
* 空Fragment(SupportRequestManagerFragment)與FragmentManager的映射關系
*/
final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments = new HashMap<>();
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
// 從三個地方去拿空Fragment,緊接著會分析
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
// 從空Fragment中拿到requestManager
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// 實例化glide用于在創(chuàng)建requestManager的時候綁定glide
Glide glide = Glide.get(context);
// 創(chuàng)建requestManager并且綁定glide
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
//如果父fragment可見,就通知glide的onStart()
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
// 第一個地方:先從FragmentManager中去拿
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
// 第二個地方:從內(nèi)存中去拿
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
//以上兩個地方都沒有,就創(chuàng)建一個空Fragment然后返回
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
//記錄映射關系在內(nèi)存中,臨時存的
pendingSupportRequestManagerFragments.put(fm, current);
//提交Fragment事務
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//如果提交成功之后就刪除臨時存的映射關系
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
從supportFragmentGet()方法中我們看到了Glide內(nèi)部邏輯和空Fragment的綁定過程。
不知道大家有沒有疑惑:為什么在getSupportRequestManagerFragment()方法中要在pendingSupportRequestManagerFragments中臨時保存空Fragment?
其實就是為了避免 SupportRequestManagerFragment 在一個作用域中重復創(chuàng)建。
因為commitAllowingStateLoss() 是將事務 post 到消息隊列中的,也就是說,事務是異步處理的,而不是同步處理的。假設沒有臨時保存記錄,一旦在事務異步等待執(zhí)行時調(diào)用了Glide.with(...) ,就會在該作用域中重復創(chuàng)建 Fragment。
3.4 生命周期的詳細監(jiān)聽過程
從上面小節(jié)分析可以看出,生命周期的管理,主要對Activity、Fragment和View(實質(zhì)也是Activity或Fragment)有效,其他的都是Application域,沒必須分析。所以后面的分析都是基于Activity或者Fragment的生命周期,而這兩個邏輯都是一樣的,我們還是以Fragment的分析為例。
從前面看出,每個Activity或者Fragment域都會創(chuàng)建一個空Fragment蓋在上面。下來我們就從這個空Fragment開始分析Glide的生命周期是如何受影響的。Fragment蓋的空Fragment是SupportRequestManagerFragment.java,那我們就從這里開始。
public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
ActivityFragmentLifecycle getGlideLifecycle() {
return lifecycle;
}
......
}
從3.1.1小節(jié)可以看到,創(chuàng)建RequestManager時是通過工廠創(chuàng)建的,那我們在看看這個工廠
//RequestManagerRetriever.java中
//創(chuàng)建Glide實例
Glide glide = Glide.get(context);
requestManager =factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
//factory接口
public interface RequestManagerFactory {
@NonNull
RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context);
}
//默認的RequestManager工廠
private static final RequestManagerFactory DEFAULT_FACTORY =
new RequestManagerFactory() {
@NonNull
@Override
public RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context) {
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};
RequestManager工廠在創(chuàng)建RequestManager的時候,傳入了glide和lifecycle,在RequestManager中完成綁定。
public class RequestManager
implements ComponentCallbacks2, LifecycleListener,...{
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
......
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
//lifecycle的生命周期回調(diào)加入到RequestManager中
lifecycle.addListener(this);
}
......
}
public synchronized void onStart() {
resumeRequests();
// targetTracker維持著Traker列表,每個Traker屬于Glide內(nèi)部需要監(jiān)聽生命周期的邏輯
targetTracker.onStart();
}
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
}
至此,生命周期的詳細監(jiān)聽過程就通了。
總結:調(diào)用with()創(chuàng)建RequestManager,創(chuàng)建RequestManager傳入Lifecycle對象(這個對象是在無界面 Fragment 中創(chuàng)建的),RequestManager通過Lifecycle通知Glide內(nèi)部的各個業(yè)務Traker。
當 Fragment 的生命周期變化時,無界面 Fragment會感知到生命周期變化,然后通過Lifecycle 對象將事件分發(fā)到 RequestManager,RequestManager的onStart()將事件分發(fā)給targetTracker,targetTracker分發(fā)給Glide內(nèi)部邏輯。
參考文檔: