Glide源碼剖析系列
- Android Glide源碼剖析系列(一)圖片加載請求如何感知組件生命周期
- Android Glide源碼剖析系列(二)Glide如何管理圖片加載請求
- Android Glide源碼剖析系列(三)深入理解Glide圖片加載流程
- Android Glide源碼剖析系列(四)緩存機制及其原理
為什么選擇Glide?
- 多種圖片格式的緩存,適用于更多的內(nèi)容表現(xiàn)形式(如Gif向挖、WebP关拒、縮略圖地熄、Video)
- 生命周期集成(根據(jù)Activity或者Fragment的生命周期管理圖片加載請求)Glide可以感知調(diào)用頁面的生命周期镶奉,這就是優(yōu)勢
- 高效處理Bitmap(bitmap的復(fù)用和主動回收绪抛,減少系統(tǒng)回收壓力)
- 高效的緩存策略像屋,靈活(Picasso只會緩存原始尺寸的圖片怕犁,Glide緩存的是多種規(guī)格),加載速度快且內(nèi)存開銷屑狠骸(默認Bitmap格式的不同奏甫,使得內(nèi)存開銷是Picasso的一半)
小結(jié):支持圖片格式多;Bitmap復(fù)用和主動回收凌受;生命周期感應(yīng)阵子;優(yōu)秀的緩存策略;加載速度快(Bitmap默認格式RGB565)
Glide簡單使用
Glide.with(this)
.load("https://t7.baidu.com/it/u=3779234486,1094031034&fm=193&f=GIF")
.into(imageView);
源碼分析
我們以Gide.with(activity)
方法為切入點開始分析源碼
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
只需要一行代碼胁艰,兩步輕松獲取RequestManager實例
第一步款筑、getRetriever(activity):獲取到RequestManagerRetriever實例
//1. 單例模式創(chuàng)建Glide實例
//2. 獲取RequestManagerRetriever實例
@NonNull
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(); //分兩步分析
}
1.1 使用單例模式獲取Glide實例
public static Glide get(@NonNull Context context) {
if (glide == null) {
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
1.2 繼續(xù)追蹤調(diào)用鏈:checkAndInitializeGlide() -> initializeGlide()
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
……
Glide glide = builder.build(applicationContext); //建造者模式創(chuàng)建Glide實例
……
Glide.glide = glide;
}
1.3 最終調(diào)用GlideBuilder.build()方法構(gòu)建Glide實例
@NonNull
Glide build(@NonNull Context context) {
//此處省略初始化默認配置信息代碼
……
//創(chuàng)建實例并賦值給Glide成員變量requestManagerRetriever
//這里傳入的requestManagerFactory是用來創(chuàng)建RequestManager的工廠,第2步分析
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory, experiments);
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
experiments);
}
獲取RequestManagerRetriever小結(jié):
- RequestManagerRetriever的創(chuàng)建是在Glide的初始化過程中完成的腾么;
- RequestManagerRetriever構(gòu)造方法內(nèi)傳入requestManagerFactory奈梳,用來創(chuàng)建RequestManager
第二步、get(activity) 創(chuàng)建并返回RequestManager 實例
@NonNull
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));
}
}
2.1 如果當前線程不是主線程解虱,直接轉(zhuǎn)到get(activity.getApplicationContext())中執(zhí)行攘须;否則繼續(xù)調(diào)用supportFragmentGet()方法
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call. (移除此處的Glide.get())
Glide glide = Glide.get(context);
//工廠模式創(chuàng)建requestManager,關(guān)于factory見分析2.2
requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager); //requestManager存儲到隱藏的Fragment
}
return requestManager;
}
2.2 RequestManagerFactory 初始化過程
#RequestManagerRetriever.java
//默認RequestManagerFactory
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);
}
};
public RequestManagerRetriever(
@Nullable RequestManagerFactory factory, GlideExperiments experiments) {
this.factory = factory != null ? factory : DEFAULT_FACTORY; //默認使用DEFAULT_FACTORY
handler = new Handler(Looper.getMainLooper(), this /* Callback */);
frameWaiter = buildFrameWaiter(experiments);
}
默認使用DEFAULT_FACTORY來創(chuàng)建RequestManager殴泰,見2.1requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
2.3 RequestManager構(gòu)造方法
#RequestManager.java
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
//省略其他代碼
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
}
private final Runnable addSelfToLifecycle =
new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
把當前RequestManager添加到lifecycle于宙,lifecycle是ActivityFragmentLifecycle類型浮驳,在SupportRequestManagerFragment 構(gòu)造方法中創(chuàng)建,后文會介紹SupportRequestManagerFragment類捞魁。
重點類總結(jié):
RequestManager implements LifecycleListener
- 操作和管理Glide加載圖片的請求
- 實現(xiàn)LifecycleListener接口至会,根據(jù)Activity、Fragment生命周期變化和網(wǎng)絡(luò)狀態(tài)來控制圖片加載流程
- 由RequestManagerRetriever統(tǒng)一創(chuàng)建和管理谱俭,創(chuàng)建時使用工廠模式
RequestManagerRetriever
- 作用是創(chuàng)建和復(fù)用RequestManager:使用RequestManagerRetriever.RequestManagerFactory工廠創(chuàng)建RequestManager奉件,復(fù)用SupportRequestManagerFragment 中已有的RequestManager
- 在Glide初始化時創(chuàng)建
SupportRequestManagerFragment 無視圖的Fragment
- 安全存儲RequestManager,由RequestManagerRetriever負責綁定
- 添加到當前Activity昆著,利用SupportRequestManagerFragment 的生命周期變化來控制圖片的加載流程
到目前為止县貌,我們了解了大致的框架結(jié)構(gòu),接下來正式進入到本文的主題
RequestManager如何感知組件的生命周期
我們知道感知生命周期的手段是添加隱藏的SupportRequestManagerFragment凑懂,繼續(xù)查看RequestManagerRetriever#getSupportRequestManagerFragment
源碼:
#RequestManagerRetriever.java
/** Pending adds for SupportRequestManagerFragments. */
@VisibleForTesting
//緩存已經(jīng)添加的隱藏SupportRequestManagerFragment
final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments = new HashMap<>();
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
//1. 檢查是否已經(jīng)添加了隱藏的SupportRequestManagerFragment 煤痕,使用HashMap緩存SupportRequestManagerFragment
// 2. 查找FragmentManager 中是否有可以復(fù)用的SupportRequestManagerFragment
//如果都沒有找到,創(chuàng)建一個新的SupportRequestManagerFragment接谨,
//并且添加到pendings列表&&提交到FragmentManager
SupportRequestManagerFragment current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
現(xiàn)在隱藏的SupportRequestManagerFragment已經(jīng)添加成功摆碉,繼續(xù)分析SupportRequestManagerFragment.java
源碼
private final ActivityFragmentLifecycle lifecycle;
//構(gòu)造方法
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();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
新建一個ActivityFragmentLifecycle實例賦值給SupportRequestManagerFragment的lifecycle成員變量,查看ActivityFragmentLifecycle類
class ActivityFragmentLifecycle implements Lifecycle {
//儲存LifecycleListener的列表
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
/**
* 向lifecycleListeners列表添加LifecycleListener
*/
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
//添加完成后疤坝,根據(jù)狀態(tài)執(zhí)行對應(yīng)的回調(diào)方法
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
void onStart() { //遍歷執(zhí)行onStart
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
//與onStart類似
void onStop() {
……
}
void onDestroy() {
……
}
}
使用觀察者模式兆解,在組件生命周期發(fā)生變化的時候回調(diào)相應(yīng)的操作方法。這一切都是框架幫助咱們完成的跑揉,在RequestManager構(gòu)造函數(shù)中把自身加入到ActivityFragmentLifecycle的成員變量lifecycleListeners中。
#RequestManager.java
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
//省略其他代碼
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle); //切換到主線程執(zhí)行
} else {
lifecycle.addListener(this); //添加到ActivityFragmentLifecycle成員變量lifecycleListeners
}
lifecycle.addListener(connectivityMonitor);
}
private final Runnable addSelfToLifecycle =
new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this); //添加到ActivityFragmentLifecycle成員變量lifecycleListeners
}
};
監(jiān)聽組件生命周期流程匯總:
創(chuàng)建無試圖SupportRequestManagerFragment 綁定到當前Activity埠巨;
SupportRequestManagerFragment 持有RequestManager實例历谍,RequestManager實例由RequestManagerRetriever創(chuàng)建并傳遞給SupportRequestManagerFragment ;RequestManager持有ActivityFragmentLifecycle引用辣垒,在SupportRequestManagerFragment 構(gòu)造方法中產(chǎn)生并傳遞給RequestManager望侈;
RequestManager在構(gòu)造函數(shù)中把自己加入到ActivityFragmentLifecycle.lifecycleListeners列表生命周期同步過程,以Activity調(diào)用onStart()為例:
(1)Activity調(diào)用onStart()
(2)SupportRequestManagerFragment調(diào)用onStart()
@Override
public void onStart() {
super.onStart();
lifecycle.onStart(); //==ActivityFragmentLifecycle.onStart()
}
(3)ActivityFragmentLifecycle#onStart()
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart(); //==RequestManager.onStart()
}
}
(4)RequestManager#onStart()
@Override
public synchronized void onStart() {
resumeRequests(); //啟動圖片加載請求
targetTracker.onStart(); //添加到TargetTracker勋桶,統(tǒng)一管理targets響應(yīng)組件生命周期
}
圖片加載時感知組件生命周期全過程END
結(jié)語
本文我們以一個圖片加載請求為例脱衙,大致了解了Glide感知組件生命周期的原理,但是實際項目中必然會有許多圖片加載請求同時存在例驹,所以必須要有一個機制來統(tǒng)一管理這些圖片請求捐韩,這樣才能在組件生命周期變化時改變這些請求的狀態(tài)。
關(guān)于圖片加載請求如何加入到請求列表鹃锈?Glide又是如何管理這些請求荤胁?下一篇文章繼續(xù)分析!