Glide源碼分析二——Request相關(guān)

RequestManagerRetriever

Glide在構(gòu)造時創(chuàng)建了RequestManagerRetriever,用于根據(jù)參數(shù)(Application、Activity、FragmentActivity、Fragment、View)獲取RequestManager。

如果沒有創(chuàng)建RequestManager,則會通過RequestManagerFactory創(chuàng)建。

// RequestManagerRetriever.java

private volatile RequestManager applicationManager;

public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
    // 如果沒有
    this.factory = factory != null ? factory : DEFAULT_FACTORY;
    handler = new Handler(Looper.getMainLooper(), this /* Callback */);
}


// RequestManager工廠類
public interface RequestManagerFactory {
    @NonNull
    RequestManager build(
        @NonNull Glide glide,
        @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode,
        @NonNull Context context);
}

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 RequestManager get(@NonNull Context context) {
    if (context == null) {
      // ... 省略拋異常代碼
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
    
      // 如果是在主線程,且context不是Application,則獲取對應(yīng)頁面(Activity、Fragment)的RequestManager(該RequestManger對應(yīng)著一個RequestManagerFragment)
      
      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());
      }
    }

    // 如果是在子線程或context是Application,則返回ApplicationManager(跟隨應(yīng)用生命周期)
    return getApplicationManager(context);
}

private RequestManager getApplicationManager(@NonNull Context context) {
    
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          Glide glide = Glide.get(context.getApplicationContext());
          
          // 利用工廠類創(chuàng)建一個跟隨應(yīng)用聲明周期的RequestManger
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }

    return applicationManager;
}

public RequestManager get(FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      
      // 獲取SupportFragmentManger,用于查找或添加SupportRequestMangerFragment,之后利用SupportRequestMangerFragment獲取RequestManger
      FragmentManager fm = activity.getSupportFragmentManager();
      return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
}

private RequestManager supportFragmentGet(
      @NonNull Context context,
      @NonNull FragmentManager fm,
      @Nullable Fragment parentHint,
      boolean isParentVisible) {

    // 獲取SupportRequestManagerFragment
    SupportRequestManagerFragment current =
        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
        
    // 從SupportRequestManagerFragment中獲取RequestManger
    RequestManager requestManager = current.getRequestManager();
    
    // 如果SupportRequestManagerFragment沒有RequetManger,則創(chuàng)建RequestManager并設(shè)置給SupportRequestManagerFragment
    if (requestManager == null) {
      
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
}


// 正在通過FragmentManger添加的RequestManagerFragment,之后會通過handler從該集合中移除
final Map<android.app.FragmentManager, RequestManagerFragment> pendingRequestManagerFragments =
      new HashMap<>();
      
final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments =
      new HashMap<>();

@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
      @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    
    // 是否有已經(jīng)添加了的RequeetFragment
    SupportRequestManagerFragment current =
        (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      
      // 是否有正在添加的RSupportequestFragment,沒有的話,創(chuàng)建一個,并通過FragmentManager添加,同時放入pendingSupportRequestManagerFragments中,待添加完成后會通過Handler從集合中移除
      current = pendingSupportRequestManagerFragments.get(fm);
      if (current == null) {
        current = new SupportRequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingSupportRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        
        // handler發(fā)送消息,從列表中移除正在添加的fragment
        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
}


其他get(Activity)、get(Fragment)、get(View)都差不多

public RequestManager get(@NonNull View view) {
    if (Util.isOnBackgroundThread()) {
      return get(view.getContext().getApplicationContext());
    }

    ...
    // 找到context對應(yīng)的Activity
    Activity activity = findActivity(view.getContext());
    
    if (activity == null) {
      return get(view.getContext().getApplicationContext());
    }

    
    if (activity instanceof FragmentActivity) {
      // 遞歸遍歷view的parent,如果view的哪個parent是已經(jīng)Added的SupportFragment的rootView,則返回該Fragment
      Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
      
      // 獲取Fragment或Activity的SupportRequestManagerFragment的RequestManaager
      return fragment != null ? get(fragment) : get((FragmentActivity) activity);
    }

    // 和findSupportFragment(...)類似,只是這里返回的是android.app.Fragment
    android.app.Fragment fragment = findFragment(view, activity);
    if (fragment == null) {
      return get(activity);
    }
    return get(fragment);
}


// 臨時map,存儲Fragment和它的rootView
private final ArrayMap<View, Fragment> tempViewToSupportFragment = new ArrayMap<>();

// 遞歸遍歷view的parent,如果view或view的哪個parent是已經(jīng)Added的Fragment的rootView,則返回該Fragment   
private Fragment findSupportFragment(@NonNull View target, @NonNull FragmentActivity activity) {
    tempViewToSupportFragment.clear();
    
    // 獲取Activity已添加的所有Fragment及每個Fragment的子Fragment,及對應(yīng)的fragment的RootView
    findAllSupportFragmentsWithViews(
        activity.getSupportFragmentManager().getFragments(), tempViewToSupportFragment);
        
    // 如果view或者view的parent是某個已Added的fragment的rootView,則返回該Fragment    
    Fragment result = null;
    View activityRoot = activity.findViewById(android.R.id.content);
    View current = target;
    while (!current.equals(activityRoot)) {
      result = tempViewToSupportFragment.get(current);
      if (result != null) {
        break;
      }
      if (current.getParent() instanceof View) {
        current = (View) current.getParent();
      } else {
        break;
      }
    }

    tempViewToSupportFragment.clear();
    return result;
}

// 遍歷topLevelFragments及每個Fragment的子Fragment,將Fragment和對應(yīng)的rootView放入臨時map中
private static void findAllSupportFragmentsWithViews(
      @Nullable Collection<Fragment> topLevelFragments, @NonNull Map<View, Fragment> result) {
    if (topLevelFragments == null) {
      return;
    }
    for (Fragment fragment : topLevelFragments) {
      FragmentManager may contain null values, see #1991.
      if (fragment == null || fragment.getView() == null) {
        continue;
      }
      result.put(fragment.getView(), fragment);
      findAllSupportFragmentsWithViews(fragment.getChildFragmentManager().getFragments(), result);
    }
}

get(view)的主要工作是:
遍歷該View及其parent,如果該view或其parent是該view所在的Activity的某個已經(jīng)added的Fragment的rootView,則返回該Fragment的SupportRequestManagerFragment/RequestManagerFragment的RequestManager;如果該view所在的Activity沒有添加Fragment或該view及其parent不是某個Fragment的rootView,則獲取該view所在的Activity的SupportRequestManagerFragment/RequestManagerFragment的RequestManager。

public RequestManager get(@NonNull Fragment fragment) {
    
    if (Util.isOnBackgroundThread()) {
      return get(fragment.getContext().getApplicationContext());
    } else {
      FragmentManager fm = fragment.getChildFragmentManager();
      
      // 找到Fragment已添加的SupportRequestManagerFragment,并返回其RequestManager
      return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
    }
}

get(androidx.fragment.app.Fragment)和get(android.app.Fragment)差不多,都是找到Fragment已添加的SupportRequestManagerFragment/RequestManagerFragment,并返回其RequestManager。

RequestManagerFragment

內(nèi)含lifecycle,當(dāng)RequestManagerFragment聲明周期發(fā)生變化時,會通過lifecycle通知LifecycleListener,而RequestManager實現(xiàn)了LifecycleListener,并在創(chuàng)建時被添加到了lifecycle。

RequestManger

用于生成RequestBuilder、控制Request,內(nèi)部使用RequestTracker控制Request的開始、暫停、銷毀等。

RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
      
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.requestTracker = requestTracker;
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    ...
    
}

public synchronized void pauseRequests() {
    requestTracker.pauseRequests();
}

public synchronized void resumeRequests() {
    requestTracker.resumeRequests();
}

synchronized void track(Target<?> target, Request request) {
    targetTracker.track(target);

    // 內(nèi)部調(diào)用Request#begin()開始請求數(shù)據(jù)
    requestTracker.runRequest(request);
}

...

@Override
public synchronized void onStart() {
    resumeRequests();
    targetTracker.onStart();
}

...

public <ResourceType> RequestBuilder<ResourceType> as(Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
}

public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
}

public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
}

...

RequestBuilder

用于生成Request。

// load方法會保存請求參數(shù)model
public RequestBuilder<TranscodeType> load(@Nullable Object model) {
    return loadGeneric(model);
}


private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
}

// 構(gòu)造request,并啟動
private <Y extends Target<TranscodeType>> Y into(
      Y target,
      RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    ...

    Request request = buildRequest(target, targetListener, options, callbackExecutor);

    Request previous = target.getRequest();
    
    // 如果request和target之前的request一樣,且之前的request未完成或能使用內(nèi)存中已完成的request,則復(fù)用reqeust
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      
      // 如果請求完成,調(diào)用begin()重新開始確保重新傳遞結(jié)果,觸發(fā) RequestListeners 和 Targets。如果請求失敗,調(diào)用begin()重新開始將重新啟動請求,給它一次完成的機(jī)會。如果請求已經(jīng)在運行,我們可以讓它繼續(xù)運行而不會中斷。
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        
        previous.begin();
      }
      return target;
    }

    // 清除requestManager中保存的target和對應(yīng)的Request(如果有的話,會分別從targetTracker和requestTracker中移除target和request,并將target.setRequest(null))
    requestManager.clear(target);
    target.setRequest(request);
    // 將target和對應(yīng)的request保存在requestManager中,并啟動請求(request.begin())
    requestManager.track(target, request);

    return target;
}

// buildRequest(...)直接走的這個方法
private Request buildRequestRecursive(
      Object requestLock,
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor) {

    ... // 省略一些代碼

    Request mainRequest =
        buildThumbnailRequestRecursive(
            requestLock,
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions,
            callbackExecutor);

    if (errorRequestCoordinator == null) {
      return mainRequest;
    }

    ... // 省略一些代碼
}

private Request buildThumbnailRequestRecursive(
      Object requestLock,
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor) {
    if (thumbnailBuilder != null) {
      ...
      return coordinator;
    } else if (thumbSizeMultiplier != null) {
      ...
      return coordinator;
    } else {
      // Base case: no thumbnail.
      return obtainRequest(
          requestLock,
          target,
          targetListener,
          requestOptions,
          parentCoordinator,
          transitionOptions,
          priority,
          overrideWidth,
          overrideHeight,
          callbackExecutor);
    }
}

private Request obtainRequest(
      Object requestLock,
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> requestOptions,
      RequestCoordinator requestCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      Executor callbackExecutor) {
      
    // 返回一個SingleRequest
    return SingleRequest.obtain(
        context,
        glideContext,
        requestLock,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        glideContext.getEngine(), // 獲取engine
        transitionOptions.getTransitionFactory(),
        callbackExecutor);
}

SingleRequest

public final class SingleRequest<R> implements Request, SizeReadyCallback, ResourceCallback {
    
    
    public static <R> SingleRequest<R> obtain(
      ...
      Object model,
      Class<R> transcodeClass,
      BaseRequestOptions<?> requestOptions,
      int overrideWidth,
      int overrideHeight,
      Target<R> target,
      RequestListener<R> targetListener,
      Engine engine,
      Executor callbackExecutor) {
        return new SingleRequest<>(
            ...
            model,
            transcodeClass,
            requestOptions,
            overrideWidth,
            overrideHeight,
            target,
            targetListener,
            engine,
            callbackExecutor);
    }

    private SingleRequest(
      ...
      @Nullable Object model,
      Class<R> transcodeClass,
      BaseRequestOptions<?> requestOptions,
      int overrideWidth,
      int overrideHeight,
      Target<R> target,
      RequestListener<R> targetListener,
      Engine engine,
      Executor callbackExecutor) {
        this.model = model;
        this.transcodeClass = transcodeClass;
        this.requestOptions = requestOptions;
        this.overrideWidth = overrideWidth;
        this.overrideHeight = overrideHeight;
        this.target = target;
        this.targetListener = targetListener;
        this.engine = engine;
        this.callbackExecutor = callbackExecutor;
        status = Status.PENDING;
        ...
    }
    
    
  // 開始執(zhí)行請求
  @Override
  public void begin() {
    synchronized (requestLock) {
      ...
      if (model == null) {
        ...
        onLoadFailed(new GlideException("Received null model"), logLevel);
        return;
      }

      if (status == Status.RUNNING) {
        throw new IllegalArgumentException("Cannot restart a running request");
      }

      // 如果我們在請求完成后重新啟動請求時(通常通過諸如 notifyDataSetChanged 之類的方式,它啟動對相同目標(biāo)或視圖的相同請求),我們可以簡單地使用我們上次檢索到的資源和大小并跳過獲取新大小, 開始新的加載等。如果用戶需要在視圖大小更改后重新啟動請求,則需要在開始新加載之前顯式清除視圖或目標(biāo)。
      if (status == Status.COMPLETE) {
        onResourceReady(resource, DataSource.MEMORY_CACHE);
        return;
      }

      // 如果請求不是運行中或完成狀態(tài),重新啟動它可以被看作是一個新的請求,且可以從頭開始執(zhí)行。
      status = Status.WAITING_FOR_SIZE;
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        // 如果設(shè)置了overrideWidth和overrideHeight,則修改status為running,并通過engine開始加載圖片
        onSizeReady(overrideWidth, overrideHeight);
      } else {
        // 沒有size,則先通過Target獲取大小
        target.getSize(this);
      }

      if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
          && canNotifyStatusChanged()) {
          
          // 獲取placeHolderDrawable,并回調(diào)target#onLoadStarted(drawable),如果是ImageViewTarget則會讓ImageView加載drawable
        target.onLoadStarted(getPlaceholderDrawable());
      }
      
    }
  }
  
  
  public void onSizeReady(int width, int height) {
    stateVerifier.throwIfRecycled();
    synchronized (requestLock) {
      
      if (status != Status.WAITING_FOR_SIZE) {
        return;
      }
      status = Status.RUNNING;

      ... // 省略部分對width和height的操作,主要是乘以sizeMultiplier
      
      // 加載圖片
      loadStatus =
          engine.load(
              glideContext,
              model,
              requestOptions.getSignature(),
              this.width,
              this.height,
              requestOptions.getResourceClass(),
              transcodeClass,
              priority,
              requestOptions.getDiskCacheStrategy(),
              requestOptions.getTransformations(),
              requestOptions.isTransformationRequired(),
              requestOptions.isScaleOnlyOrNoTransform(),
              requestOptions.getOptions(),
              requestOptions.isMemoryCacheable(),
              requestOptions.getUseUnlimitedSourceGeneratorsPool(),
              requestOptions.getUseAnimationPool(),
              requestOptions.getOnlyRetrieveFromCache(),
              this,
              callbackExecutor);

      ...
    }
  }
  
  
  public void onResourceReady(Resource<?> resource, DataSource dataSource) {
    ...
    Resource<?> toRelease = null;
    try {
      synchronized (requestLock) {
        loadStatus = null;
        if (resource == null) {
          GlideException exception = new GlideException("...");
          onLoadFailed(exception);
          return;
        }

        // transcodeClass就是我們想要的類型,例如Drawable、Bitmap...
        Object received = resource.get();
        if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
          toRelease = resource;
          this.resource = null;
          GlideException exception = new GlideException("..."));
          onLoadFailed(exception);
          return;
        }

        ...
        
        // 資源準(zhǔn)備好后通知target加載資源
        onResourceReady((Resource<R>) resource, (R) received, dataSource);
      }
    } finally {
      // 資源沒有被使用需要釋放掉
      if (toRelease != null) {
        engine.release(toRelease);
      }
    }
  }
  
  private void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
    
    boolean isFirstResource = isFirstReadyResource();
    
    // 修改狀態(tài)為complete
    status = Status.COMPLETE;
    this.resource = resource;

    isCallingCallbacks = true;
    try {
    
      // 是否有任何RequestListener已經(jīng)通過onResourceReady(...)通知target加載了資源
      boolean anyListenerHandledUpdatingTarget = false;
      if (requestListeners != null) {
        for (RequestListener<R> listener : requestListeners) {
          anyListenerHandledUpdatingTarget |=
              listener.onResourceReady(result, model, target, dataSource, isFirstResource);
        }
      }
      anyListenerHandledUpdatingTarget |=
          targetListener != null
              && targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);

      // 如果還沒有通過RequestListener#onResourceReady(...)更新target,則直接調(diào)用Target#onResourceReady(...)通知target加載資源
      if (!anyListenerHandledUpdatingTarget) {
        Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
        target.onResourceReady(result, animation);
      }
    } finally {
      isCallingCallbacks = false;
    }

    // 通知父RequestCoordinator請求成功了
    notifyLoadSuccess();
  }
    
}

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

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

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