Glide源碼分析

一、Glide中幾個典型的類

1、RequestManagerRetriever 用于生成RequestManager的類

public class RequestManagerRetriever implements Handler.Callback {
    
  /** The top application level RequestManager. */
  private volatile RequestManager applicationManager;

   private final Handler handler;

   private final RequestManagerFactory factory;

  @NonNull
  public RequestManager get(@NonNull Context context) {
    if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
        //step 0 
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
        //step 1
      } else if (context instanceof Activity) {
        return get((Activity) context);
        //step 2
      } else if (context instanceof ContextWrapper
          // Only unwrap a ContextWrapper if the baseContext has a non-null application context.
          // Context#createPackageContext may return a Context without an Application instance,
          // in which case a ContextWrapper may be used to attach one.
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
    //step 3
    return getApplicationManager(context);
  }

       @NonNull
  private RequestManager getApplicationManager(@NonNull Context context) {
    // Either an application context or we're on a background thread.
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          // Normally pause/resume is taken care of by the fragment we add to the fragment or
          // activity. However, in this case since the manager attached to the application will not
          // receive lifecycle events, we must force the manager to start resumed using
          // ApplicationLifecycle.

        
          Glide glide = Glide.get(context.getApplicationContext());
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }

    return applicationManager;
  }
  
 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);
        }
      };
}

}

RequestManagerRetriever 生成了RequestManager 有兩類:

  • (1) applicationManager ,該類型的RequestManager 的聲明周期和Application相同
  • (2)可以感知Activity聲明周期的RequestManager,當Activity onPause之后 會停止圖片的加載

RequestManagerRetriever.get()方法有很多重載,

  • 當傳入的參數(shù) Application 或者app在后臺時,會創(chuàng)建ApplicationRequestManager,聲明周期與Application同步
  • 當傳入的參數(shù)是Activty、Fragment或view時,創(chuàng)建的RequestManager 會與Activity的生命周期同步。

生命周期的長短,區(qū)別就在于RequestManager構(gòu)造時傳入lifecycle對象

RequestManager是如何監(jiān)聽Activity的聲明周期的?

 @NonNull
  public RequestManager get(@NonNull Fragment fragment) {
    if (Util.isOnBackgroundThread()) {
      return get(fragment.getContext().getApplicationContext());
    } else {
      FragmentManager fm = fragment.getChildFragmentManager();
      //step 1
      return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
    }
  }

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

        //step 2 創(chuàng)建SupportRequestManagerFragment 獲取Activity生命周期
    SupportRequestManagerFragment current =
        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
              //step 4 將創(chuàng)建的requestManager保存到SupportRequestManagerFragment中
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }


  @NonNull
  private SupportRequestManagerFragment getSupportRequestManagerFragment(
      @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    SupportRequestManagerFragment current =
        (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingSupportRequestManagerFragments.get(fm);
      if (current == null) {
        //step 3  創(chuàng)建一個SupportRequestManagerFragment 對象,加入到fragmentManager當中,SupportRequestManagerFragment中持有一個ActivityFragmentLifecycle 和RequestManager
        current = new SupportRequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingSupportRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

  • supportFragmentGet() 生成一個SupportRequestManagerFragment 的Fragment對象,加入到FragmentManager中,這樣生成一個SupportRequestManagerFragment就有了生命周期
  • SupportRequestManagerFragment 持有一個ActivityFragmentLifecycle對象,其生命周期與SupportRequestManagerFragment同步,是對外傳遞lifecycle的橋梁
  • 創(chuàng)建一個RequestManager對象,并將它保存在SupportRequestManagerFragment中
  • 將ActivityFragmentLifecycle生命周期對象傳遞到RequestManager中,使其可以感知Activity生命周期。

2、RequestManager

RequestManager 負責管理Request,它持有requestTracker和TargetTracker。

同一個Activity(針對非Application類型的Context) 對應(yīng)一個RequestManager,管理該Activity內(nèi)所有g(shù)lide請求。

public class RequestManager
    implements ComponentCallbacks2, LifecycleListener, ModelTypes<RequestBuilder<Drawable>> {

     protected final Glide glide;//全局glide實例
     protected final Context context;
     final Lifecycle lifecycle; //感知聲明周期
     //step 0 持有requestTracker和TargetTracker實例
     private final RequestTracker requestTracker;//追蹤request
     private final TargetTracker targetTracker = new TargetTracker();//追蹤target


       RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
        this.glide = glide;
        this.lifecycle = lifecycle;
        this.treeNode = treeNode;
        this.requestTracker = requestTracker;
        this.context = context;

        //step 1 感知網(wǎng)絡(luò)連接變化
        connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));

    
        if (Util.isOnBackgroundThread()) {
        mainHandler.post(addSelfToLifecycle);
        } else {
        //step 2 感知生命周期
        lifecycle.addListener(this);
        }
        lifecycle.addListener(connectivityMonitor);

        defaultRequestListeners =
        new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
        setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

        glide.registerRequestManager(this);
    }


    //step 3 聲明周期變化
    @Override
    public synchronized void onStart() {
        resumeRequests();
        targetTracker.onStart();
    }

    @Override
    public synchronized void onStop() {
        pauseRequests();
        targetTracker.onStop();
    }

      @Override
    public synchronized 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);
      }


     //step 4 構(gòu)建RequestBuilder
    public RequestBuilder<Bitmap> asBitmap() {
        return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
    }

    public RequestBuilder<GifDrawable> asGif() {
        return as(GifDrawable.class).apply(DECODE_TYPE_GIF);
    }

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

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

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

 }
  • RequestManager 可以感知網(wǎng)絡(luò)連接變化,當網(wǎng)絡(luò)連接恢復時,可以重新開啟圖片請求,如step 1
  • RequestManager 可以感知聲明周期,當生命周期變化時暫停、恢復Request,如step2 和step3
  • RequestManager另一個作用是 構(gòu)造RequestBuilder對象,如step 4

3、RequestBuilder

RequestBuilder 是用于構(gòu)造Request的。
RequestBuilder 繼承與BaseRequestOptions

我們先來看一下BaseRequestOptions,它用來記錄request請求的配置信息,如展位圖、優(yōu)先級、圖形變換等

public abstract class BaseRequestOptions<T extends BaseRequestOptions<T>> implements Cloneable {
  private static final int UNSET = -1;
  private static final int SIZE_MULTIPLIER = 1 << 1;
  private static final int DISK_CACHE_STRATEGY = 1 << 2;
  private static final int PRIORITY = 1 << 3;
  private static final int ERROR_PLACEHOLDER = 1 << 4;
  private static final int ERROR_ID = 1 << 5;
  private static final int PLACEHOLDER = 1 << 6;
  private static final int PLACEHOLDER_ID = 1 << 7;
  private static final int IS_CACHEABLE = 1 << 8;
  private static final int OVERRIDE = 1 << 9;
  private static final int SIGNATURE = 1 << 10;
  private static final int TRANSFORMATION = 1 << 11;
  private static final int RESOURCE_CLASS = 1 << 12;
  private static final int FALLBACK = 1 << 13;
  private static final int FALLBACK_ID = 1 << 14;
  private static final int THEME = 1 << 15;
  private static final int TRANSFORMATION_ALLOWED = 1 << 16;
  private static final int TRANSFORMATION_REQUIRED = 1 << 17;
  private static final int USE_UNLIMITED_SOURCE_GENERATORS_POOL = 1 << 18;
  private static final int ONLY_RETRIEVE_FROM_CACHE = 1 << 19;
  private static final int USE_ANIMATION_POOL = 1 << 20;

  //BaseRequestOptions request請求的參數(shù)配置信息

  //step 0 fields 32bit整型,用特定的bit位 表示是否設(shè)置了某項配置.
  private int fields;

  //step 1 用下面的屬性 來記錄具體的配置信息
  private float sizeMultiplier = 1f; //放縮系數(shù)
  //緩存策略
  @NonNull private DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.AUTOMATIC;
  //優(yōu)先級
  @NonNull private Priority priority = Priority.NORMAL;
  //加載失敗的占位圖Drawable
  @Nullable private Drawable errorPlaceholder;
    //加載失敗的占位圖資源ID
  private int errorId;
  @Nullable private Drawable placeholderDrawable;
  private int placeholderId;
  private boolean isCacheable = true;
  //指定寬高
  private int overrideHeight = UNSET;
  private int overrideWidth = UNSET;
  //請求對應(yīng)的唯一的key
  @NonNull private Key signature = EmptySignature.obtain();
  private boolean isTransformationRequired;
  private boolean isTransformationAllowed = true;
  @Nullable private Drawable fallbackDrawable;
  private int fallbackId;
  @NonNull private Options options = new Options();

  //圖形變換數(shù)組
  @NonNull
  private Map<Class<?>, Transformation<?>> transformations = new CachedHashCodeArrayMap<>();

  //最終請求的資源類型,如Drawable、bitmap、gifDrawable等
  @NonNull private Class<?> resourceClass = Object.class;
  private boolean isLocked;
  @Nullable private Resources.Theme theme;
  private boolean isAutoCloneEnabled;
  private boolean useUnlimitedSourceGeneratorsPool;
  private boolean onlyRetrieveFromCache;
  private boolean isScaleOnlyOrNoTransform = true;
  private boolean useAnimationPool;


  }

BaseRequestOptions 設(shè)置配置項時需要同時設(shè)置配置項和fileds字段(表示設(shè)置了某項配置)

  public T diskCacheStrategy(@NonNull DiskCacheStrategy strategy) {
    if (isAutoCloneEnabled) {
      return clone().diskCacheStrategy(strategy);
    }
    this.diskCacheStrategy = Preconditions.checkNotNull(strategy);
    fields |= DISK_CACHE_STRATEGY;

    return selfOrThrowIfLocked();
  }

RequestBuilder 繼承自BaseRequestOptions
使用來構(gòu)造Request的。

public class RequestBuilder<TranscodeType> extends BaseRequestOptions<RequestBuilder<TranscodeType>>
    implements Cloneable, ModelTypes<RequestBuilder<TranscodeType>> {
  
  protected static final RequestOptions DOWNLOAD_ONLY_OPTIONS =
      new RequestOptions()
          .diskCacheStrategy(DiskCacheStrategy.DATA)
          .priority(Priority.LOW)
          .skipMemoryCache(true);

  //step 0  首先 RequestBuilder 是用來構(gòu)建請求的, 它繼承自BaseRequestOptions,承載了眾多的加載配置項
  private final Context context;


  //step 1 持有RequestManager、全局的Glide和GlideContext
  private final RequestManager requestManager;
  private final Glide glide;
  private final GlideContext glideContext;

 
    //step 2 補充了額外的配置選項

  //指定待加載的資源(數(shù)據(jù)源),可以是string,URL、URI、ReqsourceID、File等
  @Nullable private Object model;
  //是否設(shè)置過model
   private boolean isModelSet;
  //指最終輸出的資源類型,如Drawable、bitmap等
  private final Class<TranscodeType> transcodeClass;
  //指定動畫過渡效果
  private TransitionOptions<?, ? super TranscodeType> transitionOptions;
  //制定了Requestlistner
  @Nullable private List<RequestListener<TranscodeType>> requestListeners;


  @Nullable private RequestBuilder<TranscodeType> thumbnailBuilder;
  @Nullable private RequestBuilder<TranscodeType> errorBuilder;
  @Nullable private Float thumbSizeMultiplier;
  private boolean isDefaultTransitionOptionsSet = true; 
  private boolean isThumbnailBuilt;



    //step 3 load方法,設(shè)置數(shù)據(jù)源
    public RequestBuilder<TranscodeType> load(@Nullable String string) {
        return loadGeneric(string);
    }

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

  //step 4  into()方法傳入Target
  public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
    return into(target, /*targetListener=*/ null, Executors.mainThreadExecutor());
  }

  @Synthetic
  <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      Executor callbackExecutor) {
    return into(target, targetListener, /*options=*/ this, callbackExecutor);
  }

  private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    Preconditions.checkNotNull(target);
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

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

    Request previous = target.getRequest();
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      if (!Preconditions.checkNotNull(previous).isRunning()) {    
        previous.begin();
      }
      return target;
    }

    requestManager.clear(target);
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
  }

    public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    Util.assertMainThread();
    Preconditions.checkNotNull(view);

    BaseRequestOptions<?> requestOptions = this;
    if (!requestOptions.isTransformationSet()
        && requestOptions.isTransformationAllowed()
        && view.getScaleType() != null) {
    
      switch (view.getScaleType()) {
        case CENTER_CROP:
          requestOptions = requestOptions.clone().optionalCenterCrop();
          break;
        case CENTER_INSIDE:
          requestOptions = requestOptions.clone().optionalCenterInside();
          break;
        case FIT_CENTER:
        case FIT_START:
        case FIT_END:
          requestOptions = requestOptions.clone().optionalFitCenter();
          break;
        case FIT_XY:
          requestOptions = requestOptions.clone().optionalCenterInside();
          break;
        case CENTER:
        case MATRIX:
        default:
          // Do nothing.
      }
    }

    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor());
  }
  
  }

a、它持有RequestManager、全局的Glide和GlideContext

b、除了基本的配置項之外,補充了額外的配置選項,如

  • model數(shù)據(jù)源、
  • transcodeClass 最終的要獲取的資源類型,如Drawable、bitmap等
  • transitionOptions 動畫過渡效果
  • requestListeners 請求監(jiān)聽器

c、RequestBuilder的一個重要方法load 用于指定數(shù)據(jù)源

4、into(target) 方法,用于生成Request,并將結(jié)果傳遞給Target

4、Target

a、Target是一個interface接口,繼承自LifecycleListener

public interface Target<R> extends LifecycleListener {
    
    //開始加載圖片,顯示placheholder
     void onLoadStarted(@Nullable Drawable placeholder);
     //加載失敗,顯示errorDrawable
     void onLoadFailed(@Nullable Drawable errorDrawable);
     //request取消,加載fallback Drawable
     void onLoadCleared(@Nullable Drawable placeholder);
     //下載成功,回調(diào)onResourceReady
     void onResourceReady(@NonNull R resource, @Nullable Transition<? super R> transition);
     //請求圖片的尺寸
     void getSize(@NonNull SizeReadyCallback cb);
     void removeCallback(@NonNull SizeReadyCallback cb);
     //保存request對象
     void setRequest(@Nullable Request request);
     Request getRequest();
}

public interface LifecycleListener {
        void onStart();
        void onStop();
        void onDestroy();
}

Target 具有LifecycleListener的能力,可以感知生命周期(onStrat、onStop、onDestroy)

同時具有以下能力

  • onLoadStarted,開始加載圖片,顯示placheholder
  • onLoadFailed,加載失敗,顯示errorDrawable
  • request取消,加載fallback Drawable
  • onResourceRead,下載成功,將resource資源回調(diào)給Target
  • getSize,請求圖片尺寸
  • setRequest(),getRequest() 持有Request對象

b、BaseTarget

BaseTarget 持有request屬性,實現(xiàn)了setRequest、getRequest方法

public abstract class BaseTarget<Z> implements Target<Z> {
  private Request request;

  @Override
  public void setRequest(@Nullable Request request) {
    this.request = request;
  }

  @Override
  @Nullable
  public Request getRequest() {
    return request;
  }
  
  //其他父類方法
  ...
}

c、ViewTarget

ViewTarget 集成自BaseTarget,持有一個View對象。

  • Request 保存在了view對象的tag中
  • 實現(xiàn)了getSize() ,通過SizeDeterminer 計算Bitmap 最終的尺寸,再通過SizeReadyCallback進行回調(diào).
  • 注冊了View的OnAttachStateChangeListener,onViewAttachedToWindow時resumeRequest,onViewDetachedFromWindow時 pauseRequest
public abstract class ViewTarget<T extends View, Z> extends BaseTarget<Z> {


    //step 0  ViewTarget 持有一個View 
   protected final T view;
   private final SizeDeterminer sizeDeterminer;
   @Nullable private OnAttachStateChangeListener attachStateListener;

    public ViewTarget(@NonNull T view) {
        this.view = Preconditions.checkNotNull(view);
        sizeDeterminer = new SizeDeterminer(view);
    }
    //step 2 實現(xiàn)了計算ImageView尺寸的方式,通過sizeDeterminer計算,計算完成通過SizeReadyCallback 回傳
    public void getSize(@NonNull SizeReadyCallback cb) {
     sizeDeterminer.getSize(cb);
    }

   @Override
  public void setRequest(@Nullable Request request) {
    setTag(request);
  }
  //step 1  request 保存在了View的Tag上
   private void setTag(@Nullable Object tag) {
    isTagUsedAtLeastOnce = true;
    view.setTag(tagId, tag);
  }

  //step 2 監(jiān)測View的attach, attach時 resumeRequest,dettach時pauseRequest
  public final ViewTarget<T, Z> clearOnDetach() {
    if (attachStateListener != null) {
      return this;
    }
    attachStateListener =
        new OnAttachStateChangeListener() {
          @Override
          public void onViewAttachedToWindow(View v) {
            resumeMyRequest();
          }

          @Override
          public void onViewDetachedFromWindow(View v) {
            pauseMyRequest();
          }
        };
    maybeAddAttachStateListener();
    return this;
  }
}

d、 ImageViewTarget

ImageViewTarget 繼承自ViewTarget,重點實現(xiàn)的是Animatable動畫相關(guān)的操作

public abstract class ImageViewTarget<Z> extends ViewTarget<ImageView, Z>
    implements Transition.ViewAdapter {

     @Nullable private Animatable animatable;

     //step 0 實現(xiàn)了Transition.ViewAdapter
      public Drawable getCurrentDrawable() {
            return view.getDrawable();
        }

    public void setDrawable(Drawable drawable) {
        view.setImageDrawable(drawable);
    }

    //step 1 實現(xiàn)了onLoadFailed()、onLoadFailed()、onLoadCleared(), 顯示placheHolder、errorDrawable、fallbackDrawable
    public void onLoadStarted(@Nullable Drawable placeholder) {
        super.onLoadStarted(placeholder);
        setDrawable(placeholder);
    }

     public void onLoadFailed(@Nullable Drawable errorDrawable) {
        super.onLoadFailed(errorDrawable);
        setDrawable(errorDrawable);
    }

     public void onLoadCleared(@Nullable Drawable placeholder) {
        super.onLoadCleared(placeholder);
        if (animatable != null) {
         animatable.stop();
         }
        setDrawable(placeholder);
    }

     //實現(xiàn)了onResourceReady 資源備妥后 顯示動畫
      @Override
    public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
        if (transition == null || !transition.transition(resource, this)) {
        setResourceInternal(resource);
        } else {
        maybeUpdateAnimatable(resource);
        }
     }

     //step 2 onStart()啟動動畫,onStop() 通知動畫
      @Override
    public void onStart() {
        if (animatable != null) {
         animatable.start();
        }
    }

     @Override
      public void onStop() {
        if (animatable != null) {
          animatable.stop();
        }
      }

    protected abstract void setResource(@Nullable Z resource);
 }
  • 實現(xiàn)了Transition.ViewAdapter 接口

Transition.ViewAdapter

public interface Transition<R> {
  interface ViewAdapter {
    View getView();
    Drawable getCurrentDrawable();
    void setDrawable(Drawable drawable);
  }
}
  • 實現(xiàn)了onLoadFailed()、onLoadFailed()、onLoadCleared() 方法,分別顯示placheHolder,errorDrawable、fallbackDrawable

  • 實現(xiàn)onResourceReady 動畫顯示Drawable

  • 生命周期onStart()、onStop() 啟動或停止動畫

  • setResource() 是個虛方法,留給子類實現(xiàn)

e、BitmapImageViewTarget

BitmapImageViewTarget 繼承自ImageViewTarget,指定了Resource的類型為Bitmap,實現(xiàn)了setResource方法

public class BitmapImageViewTarget extends ImageViewTarget<Bitmap> {
  // Public API.
  @SuppressWarnings("WeakerAccess")
  public BitmapImageViewTarget(ImageView view) {
    super(view);
  }

  /**
   *
   * @param resource The bitmap to display.
   */
  @Override
  protected void setResource(Bitmap resource) {
    view.setImageBitmap(resource);
  }
}

f、DrawableImageViewTarget

DrawableImageViewTarget 繼承自ImageViewTarget,指定了Resource類型為Drawable,并實現(xiàn)了setResource方法

public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {

  public DrawableImageViewTarget(ImageView view) {
    super(view);
  }

  @Override
  protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);
  }
}

7、Request

Request 實現(xiàn)將resource加載到Target中,是一個接口,具體實現(xiàn)由子類實現(xiàn)。


//一個Request 實現(xiàn)如何加載resource到Target中
public interface Request {
  //開始異步加載
  void begin();
  //停止加載,釋放資環(huán)
  void clear();
  void pause();
  boolean isRunning();
  boolean isComplete();
  boolean isCleared();
  boolean isAnyResourceSet();
  boolean isEquivalentTo(Request other);
}

SingleRequest 是Request的實現(xiàn)類,SingleRequest內(nèi)部定義了一個Status枚舉,標記Request請求所處的階段

public final class SingleRequest<R> implements Request, SizeReadyCallback, ResourceCallback {
  
   private enum Status {
    /** Created but not yet running. */
    PENDING,
    /** In the process of fetching media. */
    RUNNING,
    /** Waiting for a callback given to the Target to be called to determine target dimensions. */
    WAITING_FOR_SIZE,
    /** Finished loading media successfully. */
    COMPLETE,
    /** Failed to load media, may be restarted. */
    FAILED,
    /** Cleared by the user with a placeholder set, may be restarted. */
    CLEARED,
  }


}
  • PENDING :Request剛創(chuàng)建,尚未執(zhí)行
  • WAITING_FOR_SIZE:等待獲取Target的尺寸,獲取成功后,會通過callback 傳遞到Request的onSizeReady()
  • RUNNING:Target尺寸確定了之后,進入Running狀態(tài),開始加載Resource
  • COMPLETE:加載成功,status切換為成功狀態(tài)
  • FAILED:加載失敗狀態(tài)
  • CLEARED:資源被清除

所以常規(guī)的狀態(tài)流應(yīng)該是:

PENDING->WAITING_FOR_SIZE->RUNNING->COMPLETE

二、glide使用三板斧

   Glide.with(iv_glide).load(url).into(iv_glide)

1、with 操作符返回一個RequestManager

Glide.with(context) 返回一個RequestManager
 public static RequestManager with(@NonNull View view) {
    return getRetriever(view.getContext()).get(view);
  }
  
  • step == 0 Glide.get()會進行Glide的全局初始化
  • step == 1 getRetriever() 獲取以一個RequestManagerRetriever對象
  • step == 2 RequestManagerRetriever.get() 返回一個RequestManger對象

glide.with()可以傳入不同的context,返回不同的RequestManager

    public RequestManager get(@NonNull Context context) {
    if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
        return get((Activity) context);
      } else if (context instanceof ContextWrapper
          // Only unwrap a ContextWrapper if the baseContext has a non-null application context.
          // Context#createPackageContext may return a Context without an Application instance,
          // in which case a ContextWrapper may be used to attach one.
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }

    return getApplicationManager(context);
  }

以傳入FragmentActivity為例子,

  • 當前處于后臺時,會創(chuàng)建給ApplciationRequestManager
  • 當處于前臺時,會創(chuàng)建一個無界面的SupportRequestManagerFragment 加入到FragmentManager中,SupportRequestManagerFragment中維護一個ActivityFragmentLifecycle,與Activity生命周期同步,此lifeCycle會傳遞到Request中,感知Activity聲明周期。
@NonNull
  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));
    }
  }
  
  
  @NonNull
  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;
  }

2、load 操作符返回RequestBuilder

RequestManager.load方法返回RequestBuilder對象,并指定了數(shù)據(jù)源(如圖片加載鏈接)
RequestManager.hava

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

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

  public <ResourceType> RequestBuilder<ResourceType> as(
      @NonNull Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
  }
  • load默認是產(chǎn)生RequestBuilder<Drawable>,指定輸出的resource類型是Drawable
  • asBitmap、asGif 方法可以指定資源類型為Bitmap或者GifDrawable
  public RequestBuilder<Bitmap> asBitmap() {
    return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
  }
   public RequestBuilder<GifDrawable> asGif() {
    return as(GifDrawable.class).apply(DECODE_TYPE_GIF);
  }
  • RequestBuilder 鏈式調(diào)用可以指定Request的各種配置和屬性
    Glide.with(iv_glide)
            .load(url)
            .placeholder(R.drawable.ic_launcher_background)
            .error(R.drawable.ic_launcher_foreground)
            .fallback(R.drawable.ic_launcher_foreground)
            .transform(RoundTransformation(50), RotateTransformation(90F))
            .transition(DrawableTransitionOptions.withCrossFade(1000 * 10))
            .into(iv_glide)

3、into操作符

into操作符傳入一個ImageView,觸發(fā)圖片獲取和加載

public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {

    //step 0 生成一個BitMapImageViewTarget 或者DrawableImageViewTarget
     return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor());
}



private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    Preconditions.checkNotNull(target);

    //step 1 構(gòu)造一個SingleRequest
    Request request = buildRequest(target, targetListener, options, callbackExecutor);

    requestManager.clear(target);
    target.setRequest(request);
    //step 2 通過requestManager 追蹤,啟動 SingleRequest的執(zhí)行
    requestManager.track(target, request);

    return target;
  }
  • 首先通過傳入的ImageView 構(gòu)造了,根據(jù)TranscodeType 生成了一個ImageViewTarget
public class ImageViewTargetFactory {
  @NonNull
  @SuppressWarnings("unchecked")
  public <Z> ViewTarget<ImageView, Z> buildTarget(
      @NonNull ImageView view, @NonNull Class<Z> clazz) {
    if (Bitmap.class.equals(clazz)) {
      return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
    } else if (Drawable.class.isAssignableFrom(clazz)) {
      return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
    } else {
      throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
  }
}

  • 通過上一步生成的ImageViewTarget,構(gòu)造SingleRequest
  • 將SingleRequest 傳入requestManager,觸發(fā)圖片的加載過程。
 requestManager.track(target, request);
 
##RequestManager.java
 synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }

RequestTracker.java

 public void runRequest(@NonNull Request request) {
    requests.add(request);
    if (!isPaused) {
      request.begin();
    } else {
      request.clear();
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Paused, delaying request");
      }
      pendingRequests.add(request);
    }
  }

至此Glide操作的三板斧執(zhí)行完畢

三、Reqeust 請求是如何執(zhí)行的

3.1、RequestBuilder.into()方式是真正圖片加載的入口

RequestBuilder.java 
 public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view){

    //step 0  產(chǎn)生ImageViewTarget 
    target = glideContext.buildImageViewTarget(view, transcodeClass)
    //step 1  生成一個SingleRequest對象
     Request request = buildRequest(target, targetListener, options, callbackExecutor);

     //先取消target上的圖片加載(如果有的話)
    requestManager.clear(target);
    target.setRequest(request);
    //step 2 將target、request加入到requestManager
    requestManager.track(target, request);

 }

#RequestManager.java
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
}

#RequestTracker.java 
public void runRequest(@NonNull Request request) {

    //step 3  將request加入到requests隊列
    requests.add(request);
    if (!isPaused) { //RequestTracker不是pause狀態(tài),則直接啟動request
      request.begin();
    } else { //RequestTracker處于pause狀態(tài),則將request加入到pendingRequest待執(zhí)行Request隊列
      request.clear();
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Paused, delaying request");
      }
      pendingRequests.add(request);
    }
  }

代碼的調(diào)用流程為

RequestBuilder.into()->
RequestMananger.track()->
requestTracker.runRequest()->
request.begin()

3.2、request.begin()

request 實際SingleRequest實例

#SingleRequest.java
public void begin() {

    //step 0  model 為空 -> onLoadFailed
    if (model == null) {
        onLoadFailed(new GlideException("Received null model"), logLevel);
        return;
      }
    // 正在執(zhí)行的Request不允許再次執(zhí)行
    if (status == Status.RUNNING) {
        throw new IllegalArgumentException("Cannot restart a running request");
    }

    //執(zhí)行完成,回調(diào)onResourceReady 回傳圖片文件
    if (status == Status.COMPLETE) {
        onResourceReady(resource, DataSource.MEMORY_CACHE);
        return;
    }

    // step 1 最初status狀態(tài) 是WAITING_FOR_SIZE,等待獲取目標圖片大小
    status = Status.WAITING_FOR_SIZE;
    //如果指定了overrideWidth和overrideHeight 則直接使用回調(diào)onSizeReady()
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        onSizeReady(overrideWidth, overrideHeight);
      } else {
        //用于未指定圖片大小,則交由target取獲取目標圖片的大小(對于ImageViewTarget size一般是ImageViewK控件的尺寸)
        target.getSize(this);
      }

    //step 2 回調(diào)onLoadingStarted
    if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
          && canNotifyStatusChanged()) {
        target.onLoadStarted(getPlaceholderDrawable());
     }
}




@Override
  public void onSizeReady(int width, int height) {
    //step 3  獲取target尺寸成功,調(diào)用Engine.load開始加載圖片
    status = Status.RUNNING;
    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);
  }
  
  //step 4 
private void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
    // We must call isFirstReadyResource before setting status.
    boolean isFirstResource = isFirstReadyResource();
    status = Status.COMPLETE;
    this.resource = resource;

    ...
    Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
    target.onResourceReady(result, animation);

    notifyLoadSuccess();
  }
  • step 0

可以看到判斷model變量為null,就回調(diào)onLoadFailed方法,這個方法就會設(shè)置我們配置的error placeholder資源。這里的model變量就是我們通過load(myUrl)方法傳入的圖片地址。

  • step 1
    判斷overrideWidth, overrideHeight是否可用。
    如果設(shè)置了override(int width, int height) ,直接處理onSizeReady方法邏輯;如果沒有設(shè)置override,Glide就會等到系統(tǒng)計算完組件(一般是ImageView組件)寬高后再回調(diào)onSizeReady。這兩種情況最后都會調(diào)用onSizeReady方法。

  • step 2
    已經(jīng)開始了圖片的加載,回調(diào)設(shè)置placeholderDrawable,顯示placeHolder占位圖。

  • step 3 獲取圖片尺寸成功,engine.load 開始圖片的加載過程

  • step 4
    image加載完成回調(diào)。這里是加載、縮放、轉(zhuǎn)換之后的數(shù)據(jù),可直接用于UI顯示。

3.3、engine.load()

  #Engine.java
  public <R> LoadStatus load(
      GlideContext glideContext,
      Object model,
      Key signature,
      int width,
      int height,
      Class<?> resourceClass,
      Class<R> transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map<Class<?>, Transformation<?>> transformations,
      boolean isTransformationRequired,
      boolean isScaleOnlyOrNoTransform,
      Options options,
      boolean isMemoryCacheable,
      boolean useUnlimitedSourceExecutorPool,
      boolean useAnimationPool,
      boolean onlyRetrieveFromCache,
      ResourceCallback cb,
      Executor callbackExecutor) {

      //(1)生成緩存key
        EngineKey key =
        keyFactory.buildKey(
            model,
            signature,
            width,
            height,
            transformations,
            resourceClass,
            transcodeClass,
            options);

     //(2)從內(nèi)存緩存中匹配目標圖片資源(又細分為activeResources和cache)
     memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

     if (memoryResource == null) {
        //(4) 內(nèi)存緩存未命中,則嘗試從磁盤緩存或者網(wǎng)絡(luò)加載圖片
        return waitForExistingOrStartNewJob(
            glideContext,
            model,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            options,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache,
            cb,
            callbackExecutor,
            key,
            startTime);
      }
    }

   //(3)若內(nèi)存緩存命中,則直接返回onResourceReady
   cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);

}

默認情況下,Glide 會在開始一個新的圖片請求之前檢查以下多級的緩存:

活動資源 (Active Resources) - 正在顯示的資源
內(nèi)存緩存 (Memory cache) - 顯示過的資源
資源類型(Resource) - 被解碼、轉(zhuǎn)換后的資源
數(shù)據(jù)來源 (Data) - 源文件(未處理過)資源

也就是內(nèi)存緩存+磁盤緩存。

首先engine.load方法 首先會生成EngineKey,然嘗試從內(nèi)存中檢索緩存,如注釋(2)

先后從Active Resources和Memory cache中檢索緩存,若命中,則直接直接回調(diào)onResourceReady,如注釋(3)

 @Nullable
  private EngineResource<?> loadFromMemory(
      EngineKey key, boolean isMemoryCacheable, long startTime) {
    if (!isMemoryCacheable) {
      return null;
    }

    EngineResource<?> active = loadFromActiveResources(key);
    if (active != null) {
      return active;
    }

    EngineResource<?> cached = loadFromCache(key);
    if (cached != null) {
      return cached;
    }

    return null;
  }

若內(nèi)存緩存未命中,則嘗試啟動解碼任務(wù)開始解碼圖片,如注釋(4)

private <R> LoadStatus waitForExistingOrStartNewJob(
      GlideContext glideContext,
      Object model,
      Key signature,
      int width,
      int height,
      Class<?> resourceClass,
      Class<R> transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map<Class<?>, Transformation<?>> transformations,
      boolean isTransformationRequired,
      boolean isScaleOnlyOrNoTransform,
      Options options,
      boolean isMemoryCacheable,
      boolean useUnlimitedSourceExecutorPool,
      boolean useAnimationPool,
      boolean onlyRetrieveFromCache,
      ResourceCallback cb,
      Executor callbackExecutor,
      EngineKey key,
      long startTime) {

 
     //創(chuàng)建EngineJob,EngineJob是一個Runnable
    EngineJob<R> engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);

    //創(chuàng)建DecodeJob
    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, callbackExecutor);

    //啟動decodeJob
    engineJob.start(decodeJob);

    return new LoadStatus(cb, engineJob);
  }

DecodeJob是整個流程中的重點,我們重點看EngineJob做了哪些事情

//執(zhí)行EngineJob的start方法
//start方法就是根據(jù)diskCacheStrategy策略獲取一個executor來執(zhí)行DecodeJob
public void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    //這里根據(jù)緩存策略,決定使用哪個Executor。默認情況返回diskCacheExecutor。
    //共三種執(zhí)行器:diskCacheExecutor、sourceExecutor、sourceUnlimitedExecutor對應(yīng)文章前面給出的流程圖。
    GlideExecutor executor = decodeJob.willDecodeFromCache()
        ? diskCacheExecutor
        : getActiveSourceExecutor();
    executor.execute(decodeJob);
  }

//當然,DecodeJob實現(xiàn)了Runnable接口。直接來看它的run方法。
 @Override
  public void run() {
    runWrapped();//看這里!
  }

//接著看runWrapped方法。
//RunReason是一個枚舉,默認值為INITIALIZE。區(qū)分任務(wù)目的。
private void runWrapped() {
     switch (runReason) {
      case INITIALIZE:
        stage = getNextStage(Stage.INITIALIZE);
        currentGenerator = getNextGenerator();
        runGenerators();
        break;
      case SWITCH_TO_SOURCE_SERVICE:
        runGenerators();
        break;
      case DECODE_DATA:
        decodeFromRetrievedData();
        break;
      default:
        throw new IllegalStateException("Unrecognized run reason: " + runReason);
    }
  }
  
  //獲取任務(wù)執(zhí)行階段:初始化、讀取轉(zhuǎn)換后的緩存、讀取原文件緩存、原文件加載、結(jié)束狀態(tài)。
  private Stage getNextStage(Stage current) {
    switch (current) {
      case INITIALIZE:
        return diskCacheStrategy.decodeCachedResource()
            ? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
      case RESOURCE_CACHE:
        return diskCacheStrategy.decodeCachedData()
            ? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
      case DATA_CACHE:
        // Skip loading from source if the user opted to only retrieve the resource from cache.
        return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
      case SOURCE:
      case FINISHED:
        return Stage.FINISHED;
      default:
        throw new IllegalArgumentException("Unrecognized stage: " + current);
    }
  }

//根據(jù)上一個方法確定的stage,創(chuàng)建對應(yīng)的Generator(可把它簡單理解成資源加載器)
  private DataFetcherGenerator getNextGenerator() {
    switch (stage) {
      case RESOURCE_CACHE:
        //從轉(zhuǎn)換后的緩存中讀取文件
        return new ResourceCacheGenerator(decodeHelper, this);
      case DATA_CACHE:
       //從原文件緩存中讀取文件
        return new DataCacheGenerator(decodeHelper, this);
      case SOURCE:
       //沒有緩存,重新加載資源(比如:網(wǎng)絡(luò)圖片、本地文件)
        return new SourceGenerator(decodeHelper, this);
      case FINISHED:
        return null;
      default:
        throw new IllegalStateException("Unrecognized stage: " + stage);
    }
  }

 //這里開始加載執(zhí)行
  private void runGenerators() {
    currentThread = Thread.currentThread();
    startFetchTime = LogTime.getLogTime();
    boolean isStarted = false;
    //這里Generator.startNext()方法中就是加載過程,如果成功加載則返回true并跳出循環(huán),否則切換Generator繼續(xù)執(zhí)行。
    while (!isCancelled && currentGenerator != null
        && !(isStarted = currentGenerator.startNext())) {
      stage = getNextStage(stage);
      currentGenerator = getNextGenerator();

     //如果任務(wù)執(zhí)行到去加載資源(也就是沒有命中磁盤緩存),且切換任務(wù)執(zhí)行環(huán)境
      if (stage == Stage.SOURCE) {
        reschedule();
        return;
      }
    }
    // We've run out of stages and generators, give up.
    if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
      notifyFailed();
    }

    // Otherwise a generator started a new load and we expect to be called back in
    // onDataFetcherReady.
  }
 
  @Override
  public void reschedule() {
    //更改執(zhí)行目標為:SOURCE服務(wù)。當然也只有在stage == Stage.SOURCE的情況下會被調(diào)用。
    runReason = RunReason.SWITCH_TO_SOURCE_SERVICE;
    callback.reschedule(this);//這里callback正是EngineJob。
  } 
  
  //代碼跟進EngineJob類中,可以看到實現(xiàn)方法。
  @Override
  public void reschedule(DecodeJob<?> job) {
    // 可以看到,這里獲取的SourceExecutor來執(zhí)行decodeJob。
    //也就巧妙地將此decodeJob任務(wù)從cacheExecutor切換到了SourceExecutor,這樣分工協(xié)作更加高效。
    getActiveSourceExecutor().execute(job);
  }
 

從最開始沒有命中內(nèi)存緩存開始,然后執(zhí)行Engine的start方法,默認情況會獲取到cacheExecutor執(zhí)行器來執(zhí)行decodeJob任務(wù);繼續(xù)decodeJob的run方法,因為RunReason==INITIALIZE,接著獲取stage,默認會返回Stage.RESOURCE_CACHE,這時通過getNextGenerator就返回了ResourceCacheGenerator加載器,緊接著就是調(diào)用 ResourceCacheGenerator的startNext方法 ,從轉(zhuǎn)換后的緩存中讀取已緩存的資源,如果命中則結(jié)束任務(wù)并回調(diào)結(jié)果,反之,任務(wù)切換到DataCacheGenerator加載器繼續(xù)執(zhí)行,若還是未命中,則切換到SourceGenerator加載器(第一次加載,由于沒有任何緩存,就會走到這里),這時會通過任務(wù)調(diào)度,將線程運行環(huán)境切換到 SourceExecutor執(zhí)行器來執(zhí)行,最后,待SourceGenerator加載完成后結(jié)束任務(wù),回調(diào)結(jié)果,流程結(jié)束。


image

參考文章

http://m.itdecent.cn/p/7c72e040087c

?著作權(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)容