Glide流程分析
說到圖片加載框架,大家最熟悉的莫過于Glide了,但我卻不推薦簡(jiǎn)歷上寫熟悉Glide, 除非你熟讀它的源碼,或者參與Glide的開發(fā)和維護(hù)。然而很多小伙伴對(duì)于Glide的流程及其源碼解讀總是無從下手,本篇就從三條主線來分析一下Glide流程及源碼!
第一條主線
加入隊(duì)列流程:
RequestManager with = Glide.with(this);
RequestBuilder<Drawable> load = with.load(url);
load.into(iv); // 前面的暫時(shí)先不看,當(dāng)調(diào)用into方法后,說明加載圖片的請(qǐng)求才真正開始
繼續(xù)調(diào)用
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions);
繼續(xù)跟蹤,會(huì)發(fā)現(xiàn)以下代碼
requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);//發(fā)送請(qǐng)求開始的地方
void track(Target<?> target, Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);//從名字看叫運(yùn)行請(qǐng)求
}
繼續(xù)跟蹤
通過該方法得知Glide也有兩個(gè)隊(duì)列;運(yùn)行隊(duì)列和等待隊(duì)列;
public void runRequest(Request request) {
requests.add(request);//加入運(yùn)行隊(duì)列;
if (!isPaused) {
request.begin();//開始執(zhí)行
} else {
pendingRequests.add(request);//加入等待隊(duì)列
}
}
第二條主線
請(qǐng)求如何運(yùn)行?
在第一條主線中,request.begin()方法就是真正開始執(zhí)行請(qǐng)求的時(shí)候;先找到request的實(shí)現(xiàn)類:SingleRequest,找到其begin方法;
為什么找到的是SingleRequest?
在第一條主線的RequestBuilder.into方法中有一句代碼;
Request request = buildRequest(target, targetListener, options);
繼續(xù)跟蹤它
buildRequestRecursive() 找到構(gòu)建request的方法;
在該方法中,又能跟蹤到
Request mainRequest = buildThumbnailRequestRecursive()
繼續(xù)跟蹤
Request fullRequest =
obtainRequest(
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight);
上述代碼塊最終調(diào)用的是SingleRequest.obtain()方法,從而得到一個(gè)SingleRequest對(duì)象;所以能得出結(jié)論,request.begin()方法被調(diào)用時(shí),即調(diào)用了SingleRequest的begin方法;繼續(xù)跟蹤begin方法,會(huì)發(fā)現(xiàn)onSizeReady方法;
onSizeReady(overrideWidth, overrideHeight);
在begin方法中跟蹤到engine.load方法,如下(只抽取了部分代碼):
// 從活動(dòng)緩存中獲取
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
cb.onResourceReady(active, DataSource.MEMORY_CACHE);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
// 從內(nèi)存緩存中獲取
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
// 硬盤緩存,硬盤緩存也是io操作,所以也使用了線程池;動(dòng)畫線程池
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
current.addCallback(cb);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
return new LoadStatus(cb, current);
}
EngineJob<R> engineJob =
engineJobFactory.build(
key,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache);
DecodeJob<R> decodeJob =
decodeJobFactory.build(
glideContext,
model,
key,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
onlyRetrieveFromCache,
options,
engineJob);
jobs.put(key, engineJob);
engineJob.addCallback(cb);
engineJob.start(decodeJob); //具體的加載,engineJob為加載管理類,decodeJob則為將返回的圖片數(shù)據(jù)進(jìn)行編碼管理的類;
調(diào)用engineJob.start()方法后,則會(huì)執(zhí)行以下代碼:
public void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
executor.execute(decodeJob);
}
繼續(xù)跟蹤找到DecodeJob的run方法;
DecodeJob.run() 繼續(xù)調(diào)用 runWrapped(); 再繼續(xù)調(diào)用getNextGenerator()
private DataFetcherGenerator getNextGenerator() {
switch (stage) {
case RESOURCE_CACHE:
return new ResourceCacheGenerator(decodeHelper, this);
case DATA_CACHE:
return new DataCacheGenerator(decodeHelper, this);
case SOURCE:
// 根據(jù)主線我們目前都先不去處理跟Cache相關(guān)的類,直接進(jìn)入SourceGenerator;這里使用了設(shè)計(jì)模式-狀態(tài)模式;(請(qǐng)自行根據(jù)第二節(jié)內(nèi)容進(jìn)行查詢)
return new SourceGenerator(decodeHelper, this);
case FINISHED:
return null;
default:
throw new IllegalStateException("Unrecognized stage: " + stage);
}
}
繼續(xù)跟蹤到SourceGenerator類中的startNext方法;
loadData.fetcher.loadData(helper.getPriority(), this);
根據(jù)fetcher找到HttpUrlFetcher,并找到對(duì)應(yīng)的loadData方法;最終發(fā)現(xiàn)Glide是通過HttpUrlConnection訪問的服務(wù)器,并返回最終的stream;
問題來了?我怎么知道是這個(gè)類的?為什么不是其他類?在這里代碼就看不懂了,怎么辦?猜測(cè);
既然應(yīng)該不是再繼續(xù)從緩存拿,而應(yīng)該要去訪問網(wǎng)絡(luò)了;所以找到具體訪問網(wǎng)絡(luò)的;發(fā)現(xiàn)找不到,怎么辦?

找它的實(shí)現(xiàn)類,有一個(gè)HttpUrlFetcher,那它在哪里初始化的?

通過Find Usages找到哪里調(diào)用了--->找到了HttpGlideUrlLoader;
再看這個(gè)方法HttpGlideUrlLoader哪里調(diào)用了;

找到了Glide,繼續(xù)往上尋找,找打了Glide種的build方法 ,找就能找到Glide.get(context);方法
第三條主線
隊(duì)列怎么維護(hù)的?在MainActivity中我們調(diào)用了如下代碼:
RequestManager with = Glide.with(this);
繼續(xù)跟蹤到
getRetriever(activity).get(activity)//這里得到了一個(gè)RequestManagerRetriever對(duì)象,再通過RequestManagerRetriever調(diào)用get方法得到RequestManager
繼續(xù)往下
androidx.fragment.app.FragmentManager fm = activity.getSupportFragmentManager();
return this.supportFragmentGet(activity, fm, (Fragment)null);
通過this.supportFragmentGet方法(如下代碼),最終我們得到SupportRequestManagerFragment對(duì)象;
private RequestManager supportFragmentGet(@NonNull Context context, @NonNull androidx.fragment.app.FragmentManager fm, @Nullable Fragment parentHint) {
SupportRequestManagerFragment current = this.getSupportRequestManagerFragment(fm, parentHint);//這段代碼的內(nèi)部如果能夠得到Fragment就得到,得不到就重新new一個(gè),并且這個(gè)fragment中沒有進(jìn)行任何的UI處理;
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager = this.factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
得到Fragment對(duì)象后,再將RequestManager對(duì)象賦值進(jìn)去,如果RequestManager為空,則幫助創(chuàng)建;
而RequestManager對(duì)象則是生命周期管理的重要一環(huán),因?yàn)樗鼘?shí)現(xiàn)了LifecycleListener接口,并且在創(chuàng)建RequestManager的時(shí)候,會(huì)將這個(gè)接口設(shè)置給自己;也就意味著,Glide創(chuàng)建了一個(gè)無UI的fragment,這個(gè)fragment又與RequestManager進(jìn)行綁定;當(dāng)用戶的activity或者fragment被調(diào)用,系統(tǒng)會(huì)自動(dòng)調(diào)用fragment的生命周期方法;而生命周期方法中又會(huì)回調(diào)LifecycleListener的方法,進(jìn)而調(diào)用RequestManager,RequestManager則也擁有了生命周期;
當(dāng)RequestManager的onStart方法被調(diào)用后,會(huì)通過一系列的調(diào)用,將運(yùn)行中的請(qǐng)求全部放開,進(jìn)行訪問;
當(dāng)onStop方法被調(diào)用時(shí),則將運(yùn)行中隊(duì)列的數(shù)據(jù)取出來,如果當(dāng)前請(qǐng)求正在運(yùn)行則暫停,然后將所有的數(shù)據(jù)從運(yùn)行隊(duì)列中添加到等待隊(duì)列中去;
當(dāng)onDestory方法被調(diào)用時(shí),則將運(yùn)行隊(duì)列和等待隊(duì)列中的數(shù)據(jù)全部清除;再將監(jiān)聽移除;將requestManager從Glide中的綁定關(guān)系解除;