Glide源代碼分析(一)

一直想寫(xiě)這篇文章,總怕寫(xiě)得不好。第一步,就先簡(jiǎn)單分析下Glide的代碼流程吧。首先,我們看看,是怎樣使用Glide加載圖片的。
 Glide.with(this)
 .load("https://goo.gl/images/r9XuWC")
 .into(iv);
可以看到,使用非常簡(jiǎn)單。那就簡(jiǎn)單分析下,每一步做了些什么事情。我打算分析下三個(gè)比較重要的方法。

Glide.with()

 public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }
可以看到,不管我們傳入Activity,還是Fragment,最后都會(huì)通過(guò)RequestManagerRetriever返回一個(gè)RequestManager對(duì)象。那么RequestManagerRetriever,RequestManager是干什么的?

RequestManagerRetriever:用來(lái)創(chuàng)建新的RequestManager,或者從Activity,F(xiàn)ragment拿到已經(jīng)存在的RequestManager。

RequestManager:Glide用來(lái)管理,開(kāi)啟Request的。

好了,知道了這兩個(gè)的作用之后,我們看下這個(gè)with方法的內(nèi)部實(shí)現(xiàn)。
getRetriever(activity).get(activity)
我們著重看一下RequestManagerRetriever的get方法:
 public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      FragmentManager fm = activity.getSupportFragmentManager();
      return supportFragmentGet(
          activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }
前面的判斷邏輯我們跳過(guò),著重分析下supportFragmentGet(activity, fm, /parentHint=/ null, isActivityVisible(activity))這句。
private RequestManager supportFragmentGet(
      @NonNull Context context,
      @NonNull FragmentManager fm,
      @Nullable Fragment parentHint,
      boolean isParentVisible) {
    SupportRequestManagerFragment current =
        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      // TODO(b/27524013): Factor out this Glide.get() call.
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }
這個(gè)方法比較重要??偣沧隽巳虑?。
  1. 創(chuàng)建SupportRequestManagerFragment;
  2. 創(chuàng)建RequestManager;
  3. 將SupportRequestManagerFragment與RequestManager綁定。
那么SupportRequestManagerFragment是干啥的呢?SupportRequestManagerFragment是一個(gè)無(wú)界面的Fragment,用來(lái)開(kāi)啟,停止,管理fragment,或者當(dāng)前fragment的父Activity中Glide圖片加載請(qǐng)求的。
在SupportRequestManagerFragment內(nèi)部,可以看到一個(gè)ActivityFragmentLifecycle類(lèi)型的變量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();
  }
在SupportRequestManagerFragment的生命周期中回調(diào)lifecycle的生命周期方法。
在創(chuàng)建RequestManager時(shí),我們將SupportRequestManagerFragment內(nèi)部的lifecycle傳遞進(jìn)去。這樣就將RequestManager的生命周期與Fragment,或者Activity的生命周期巧妙地結(jié)合起來(lái)。
 @Override
 public void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }
  
   @Override
   public void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }
  
  @Override
  public void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }
  
這樣,在RequestManager的生命周期中,我們可以開(kāi)啟,暫停,停止圖片加載請(qǐng)求。這也是Glide設(shè)計(jì)比較巧妙的地方。

RequestManager.load()

可以看到,重載的load方法很多,但最后都是調(diào)用loadGeneric方法。
  private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
  }
可以看到,就是進(jìn)行一些數(shù)據(jù)簡(jiǎn)單的設(shè)置。

RequestBuilder.into()

private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @NonNull RequestOptions options) {
    Util.assertMainThread();
    Preconditions.checkNotNull(target);
    //(1)判斷數(shù)據(jù)是否設(shè)置,就是我們load方法所做的事情
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

    options = options.autoClone();
    Request request = buildRequest(target, targetListener, options);

    Request previous = target.getRequest();
    //(2)中間這部分,就是一些優(yōu)化操作,熟悉主流程的話(huà)可以忽略。
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      request.recycle();
        previous.begin();
      }
      return target;
    }

    requestManager.clear(target);
    //(3)最后就是將Request請(qǐng)求與我們顯示圖片的目標(biāo)Target進(jìn)行綁定。
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
  }
into方法里面有個(gè)比較重要的一句,requestManager.track(target, request)。我們進(jìn)去看一下,里面做了什么事情。
  void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }
  
在TargetTracker內(nèi)部,有一個(gè)弱引用的Target集合。當(dāng)我們調(diào)用TargetTracker.track(Target),就將當(dāng)前Target添加到Set集合中來(lái)。加進(jìn)來(lái)干什么呢?就是在Target的生命周期回調(diào)中,執(zhí)行Target的生命周期回調(diào)。所以說(shuō),targetTracker.track(target)就是對(duì)Target進(jìn)行生命周期追蹤管理的。
下面,我們看看 requestTracker.runRequest(request)這句代碼做了什么事情。
  public void runRequest(@NonNull Request request) {
    requests.add(request);
    if (!isPaused) {
      request.begin();
    } else {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Paused, delaying request");
      }
      pendingRequests.add(request);
    }
  }
在這個(gè)RequestTracker里面,有兩個(gè)Request的集合。
  private final Set<Request> requests =
      Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());
  //未完成的Request集合
  private final List<Request> pendingRequests = new ArrayList<>();
在runRequest的時(shí)候,對(duì)RequestTracker的狀態(tài)進(jìn)行判斷,如果已經(jīng)暫停,那就加到pendingRequests里面,如果沒(méi)有暫停,那就Request真正開(kāi)始。這個(gè)地方的Request只是一個(gè)抽象的概念,到此一個(gè)簡(jiǎn)單的流程就分析結(jié)束了。在下一篇文章中,我想對(duì)這個(gè)抽象的Request內(nèi)部進(jìn)行詳細(xì)的分析。
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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