深入理解Glide源碼:三條主線分析 Glide 執(zhí)行流程

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)用了SingleRequestbegin方法;繼續(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ù)跟蹤找到DecodeJobrun方法;

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)用RequestManagerRequestManager則也擁有了生命周期;

當(dāng)RequestManageronStart方法被調(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)系解除;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容