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()方法有很多重载,

  • 当传入的参数 Application 或者app在后台时,会创建ApplicationRequestManager,声明周期与Application同步
  • 当传入的参数是Activty、Fragment或view时,创建的RequestManager 会与Activity的生命周期同步。

生命周期的长短,区别就在于RequestManager构造时传入lifecycle对象

RequestManager是如何监听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 创建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 将创建的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  创建一个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的桥梁
  • 创建一个RequestManager对象,并将它保存在SupportRequestManagerFragment中
  • 将ActivityFragmentLifecycle生命周期对象传递到RequestManager中,使其可以感知Activity生命周期。

2、RequestManager

RequestManager 负责管理Request,它持有requestTracker和TargetTracker。

同一个Activity(针对非Application类型的Context) 对应一个RequestManager,管理该Activity内所有glide请求。

public class RequestManager
    implements ComponentCallbacks2, LifecycleListener, ModelTypes> {

     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 感知网络连接变化
        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 构建RequestBuilder
    public RequestBuilder asBitmap() {
        return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
    }

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

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

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

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

 }
  • RequestManager 可以感知网络连接变化,当网络连接恢复时,可以重新开启图片请求,如step 1
  • RequestManager 可以感知声明周期,当生命周期变化时暂停、恢复Request,如step2 和step3
  • RequestManager另一个作用是 构造RequestBuilder对象,如step 4

3、RequestBuilder

RequestBuilder 是用于构造Request的。
RequestBuilder 继承与BaseRequestOptions

我们先来看一下BaseRequestOptions,它用来记录request请求的配置信息,如展位图、优先级、图形变换等

public abstract class BaseRequestOptions> 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请求的参数配置信息

  //step 0 fields 32bit整型,用特定的bit位 表示是否设置了某项配置.
  private int fields;

  //step 1 用下面的属性 来记录具体的配置信息
  private float sizeMultiplier = 1f; //放缩系数
  //缓存策略
  @NonNull private DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.AUTOMATIC;
  //优先级
  @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;
  //请求对应的唯一的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();

  //图形变换数组
  @NonNull
  private Map, 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 设置配置项时需要同时设置配置项和fileds字段(表示设置了某项配置)

  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
使用来构造Request的。

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

  //step 0  首先 RequestBuilder 是用来构建请求的, 它继承自BaseRequestOptions,承载了众多的加载配置项
  private final Context context;


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

 
    //step 2 补充了额外的配置选项

  //指定待加载的资源(数据源),可以是string,URL、URI、ReqsourceID、File等
  @Nullable private Object model;
  //是否设置过model
   private boolean isModelSet;
  //指最终输出的资源类型,如Drawable、bitmap等
  private final Class transcodeClass;
  //指定动画过渡效果
  private TransitionOptions transitionOptions;
  //制定了Requestlistner
  @Nullable private List> requestListeners;


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



    //step 3 load方法,设置数据源
    public RequestBuilder load(@Nullable String string) {
        return loadGeneric(string);
    }

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

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

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

  private > Y into(
      @NonNull Y target,
      @Nullable RequestListener 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 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数据源、
  • transcodeClass 最终的要获取的资源类型,如Drawable、bitmap等
  • transitionOptions 动画过渡效果
  • requestListeners 请求监听器

c、RequestBuilder的一个重要方法load 用于指定数据源

4、into(target) 方法,用于生成Request,并将结果传递给Target

4、Target

a、Target是一个interface接口,继承自LifecycleListener

public interface Target extends LifecycleListener {
    
    //开始加载图片,显示placheholder
     void onLoadStarted(@Nullable Drawable placeholder);
     //加载失败,显示errorDrawable
     void onLoadFailed(@Nullable Drawable errorDrawable);
     //request取消,加载fallback Drawable
     void onLoadCleared(@Nullable Drawable placeholder);
     //下载成功,回调onResourceReady
     void onResourceReady(@NonNull R resource, @Nullable Transition 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资源回调给Target
  • getSize,请求图片尺寸
  • setRequest(),getRequest() 持有Request对象

b、BaseTarget

BaseTarget 持有request属性,实现了setRequest、getRequest方法

public abstract class BaseTarget implements Target {
  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中
  • 实现了getSize() ,通过SizeDeterminer 计算Bitmap 最终的尺寸,再通过SizeReadyCallback进行回调.
  • 注册了View的OnAttachStateChangeListener,onViewAttachedToWindow时resumeRequest,onViewDetachedFromWindow时 pauseRequest
public abstract class ViewTarget extends BaseTarget {


    //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 实现了计算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 监测View的attach, attach时 resumeRequest,dettach时pauseRequest
  public final ViewTarget 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,重点实现的是Animatable动画相关的操作

public abstract class ImageViewTarget extends ViewTarget
    implements Transition.ViewAdapter {

     @Nullable private Animatable animatable;

     //step 0 实现了Transition.ViewAdapter
      public Drawable getCurrentDrawable() {
            return view.getDrawable();
        }

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

    //step 1 实现了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);
    }

     //实现了onResourceReady 资源备妥后 显示动画
      @Override
    public void onResourceReady(@NonNull Z resource, @Nullable Transition 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);
 }
  • 实现了Transition.ViewAdapter 接口

Transition.ViewAdapter

public interface Transition {
  interface ViewAdapter {
    View getView();
    Drawable getCurrentDrawable();
    void setDrawable(Drawable drawable);
  }
}
  • 实现了onLoadFailed()、onLoadFailed()、onLoadCleared() 方法,分别显示placheHolder,errorDrawable、fallbackDrawable

  • 实现onResourceReady 动画显示Drawable

  • 生命周期onStart()、onStop() 启动或停止动画

  • setResource() 是个虚方法,留给子类实现

e、BitmapImageViewTarget

BitmapImageViewTarget 继承自ImageViewTarget,指定了Resource的类型为Bitmap,实现了setResource方法

public class BitmapImageViewTarget extends ImageViewTarget {
  // 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,并实现了setResource方法

public class DrawableImageViewTarget extends ImageViewTarget {

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

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

7、Request

Request 实现将resource加载到Target中,是一个接口,具体实现由子类实现。


//一个Request 实现如何加载resource到Target中
public interface Request {
  //开始异步加载
  void begin();
  //停止加载,释放资环
  void clear();
  void pause();
  boolean isRunning();
  boolean isComplete();
  boolean isCleared();
  boolean isAnyResourceSet();
  boolean isEquivalentTo(Request other);
}

SingleRequest 是Request的实现类,SingleRequest内部定义了一个Status枚举,标记Request请求所处的阶段

public final class SingleRequest 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刚创建,尚未执行
  • WAITING_FOR_SIZE:等待获取Target的尺寸,获取成功后,会通过callback 传递到Request的onSizeReady()
  • RUNNING:Target尺寸确定了之后,进入Running状态,开始加载Resource
  • COMPLETE:加载成功,status切换为成功状态
  • FAILED:加载失败状态
  • CLEARED:资源被清除

所以常规的状态流应该是:

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为例子,

  • 当前处于后台时,会创建给ApplciationRequestManager
  • 当处于前台时,会创建一个无界面的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对象,并指定了数据源(如图片加载链接)
RequestManager.hava

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

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

  public  RequestBuilder as(
      @NonNull Class resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
  }
  • load默认是产生RequestBuilder,指定输出的resource类型是Drawable
  • asBitmap、asGif 方法可以指定资源类型为Bitmap或者GifDrawable
  public RequestBuilder asBitmap() {
    return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
  }
   public RequestBuilder asGif() {
    return as(GifDrawable.class).apply(DECODE_TYPE_GIF);
  }
  • RequestBuilder 链式调用可以指定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,触发图片获取和加载

public ViewTarget into(@NonNull ImageView view) {

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



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

    //step 1 构造一个SingleRequest
    Request request = buildRequest(target, targetListener, options, callbackExecutor);

    requestManager.clear(target);
    target.setRequest(request);
    //step 2 通过requestManager 追踪,启动 SingleRequest的执行
    requestManager.track(target, request);

    return target;
  }
  • 首先通过传入的ImageView 构造了,根据TranscodeType 生成了一个ImageViewTarget
public class ImageViewTargetFactory {
  @NonNull
  @SuppressWarnings("unchecked")
  public  ViewTarget buildTarget(
      @NonNull ImageView view, @NonNull Class clazz) {
    if (Bitmap.class.equals(clazz)) {
      return (ViewTarget) new BitmapImageViewTarget(view);
    } else if (Drawable.class.isAssignableFrom(clazz)) {
      return (ViewTarget) new DrawableImageViewTarget(view);
    } else {
      throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
  }
}

  • 通过上一步生成的ImageViewTarget,构造SingleRequest
  • 将SingleRequest 传入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) {
    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操作的三板斧执行完毕

三、Reqeust 请求是如何执行的

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

RequestBuilder.java 
 public ViewTarget into(@NonNull ImageView view){

    //step 0  产生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状态,则直接启动request
      request.begin();
    } else { //RequestTracker处于pause状态,则将request加入到pendingRequest待执行Request队列
      request.clear();
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Paused, delaying request");
      }
      pendingRequests.add(request);
    }
  }

代码的调用流程为

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;
      }
    // 正在执行的Request不允许再次执行
    if (status == Status.RUNNING) {
        throw new IllegalArgumentException("Cannot restart a running request");
    }

    //执行完成,回调onResourceReady 回传图片文件
    if (status == Status.COMPLETE) {
        onResourceReady(resource, DataSource.MEMORY_CACHE);
        return;
    }

    // step 1 最初status状态 是WAITING_FOR_SIZE,等待获取目标图片大小
    status = Status.WAITING_FOR_SIZE;
    //如果指定了overrideWidth和overrideHeight 则直接使用回调onSizeReady()
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        onSizeReady(overrideWidth, overrideHeight);
      } else {
        //用于未指定图片大小,则交由target取获取目标图片的大小(对于ImageViewTarget size一般是ImageViewK控件的尺寸)
        target.getSize(this);
      }

    //step 2 回调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尺寸成功,调用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 resource, R result, DataSource dataSource) {
    // We must call isFirstReadyResource before setting status.
    boolean isFirstResource = isFirstReadyResource();
    status = Status.COMPLETE;
    this.resource = resource;

    ...
    Transition animation = animationFactory.build(dataSource, isFirstResource);
    target.onResourceReady(result, animation);

    notifyLoadSuccess();
  }
  • step 0

可以看到判断model变量为null,就回调onLoadFailed方法,这个方法就会设置我们配置的error placeholder资源。这里的model变量就是我们通过load(myUrl)方法传入的图片地址。

  • step 1
    判断overrideWidth, overrideHeight是否可用。
    如果设置了override(int width, int height) ,直接处理onSizeReady方法逻辑;如果没有设置override,Glide就会等到系统计算完组件(一般是ImageView组件)宽高后再回调onSizeReady。这两种情况最后都会调用onSizeReady方法。

  • step 2
    已经开始了图片的加载,回调设置placeholderDrawable,显示placeHolder占位图。

  • step 3 获取图片尺寸成功,engine.load 开始图片的加载过程

  • step 4
    image加载完成回调。这里是加载、缩放、转换之后的数据,可直接用于UI显示。

3.3、engine.load()

  #Engine.java
  public  LoadStatus load(
      GlideContext glideContext,
      Object model,
      Key signature,
      int width,
      int height,
      Class resourceClass,
      Class transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map, 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)从内存缓存中匹配目标图片资源(又细分为activeResources和cache)
     memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

     if (memoryResource == null) {
        //(4) 内存缓存未命中,则尝试从磁盘缓存或者网络加载图片
        return waitForExistingOrStartNewJob(
            glideContext,
            model,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            options,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache,
            cb,
            callbackExecutor,
            key,
            startTime);
      }
    }

   //(3)若内存缓存命中,则直接返回onResourceReady
   cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);

}

默认情况下,Glide 会在开始一个新的图片请求之前检查以下多级的缓存:

活动资源 (Active Resources) - 正在显示的资源
内存缓存 (Memory cache) - 显示过的资源
资源类型(Resource) - 被解码、转换后的资源
数据来源 (Data) - 源文件(未处理过)资源

也就是内存缓存+磁盘缓存。

首先engine.load方法 首先会生成EngineKey,然尝试从内存中检索缓存,如注释(2)

先后从Active Resources和Memory cache中检索缓存,若命中,则直接直接回调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;
  }

若内存缓存未命中,则尝试启动解码任务开始解码图片,如注释(4)

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

 
     //创建EngineJob,EngineJob是一个Runnable
    EngineJob engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);

    //创建DecodeJob
    DecodeJob 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做了哪些事情

//执行EngineJob的start方法
//start方法就是根据diskCacheStrategy策略获取一个executor来执行DecodeJob
public void start(DecodeJob decodeJob) {
    this.decodeJob = decodeJob;
    //这里根据缓存策略,决定使用哪个Executor。默认情况返回diskCacheExecutor。
    //共三种执行器:diskCacheExecutor、sourceExecutor、sourceUnlimitedExecutor对应文章前面给出的流程图。
    GlideExecutor executor = decodeJob.willDecodeFromCache()
        ? diskCacheExecutor
        : getActiveSourceExecutor();
    executor.execute(decodeJob);
  }

//当然,DecodeJob实现了Runnable接口。直接来看它的run方法。
 @Override
  public void run() {
    runWrapped();//看这里!
  }

//接着看runWrapped方法。
//RunReason是一个枚举,默认值为INITIALIZE。区分任务目的。
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);
    }
  }
  
  //获取任务执行阶段:初始化、读取转换后的缓存、读取原文件缓存、原文件加载、结束状态。
  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);
    }
  }

//根据上一个方法确定的stage,创建对应的Generator(可把它简单理解成资源加载器)
  private DataFetcherGenerator getNextGenerator() {
    switch (stage) {
      case RESOURCE_CACHE:
        //从转换后的缓存中读取文件
        return new ResourceCacheGenerator(decodeHelper, this);
      case DATA_CACHE:
       //从原文件缓存中读取文件
        return new DataCacheGenerator(decodeHelper, this);
      case SOURCE:
       //没有缓存,重新加载资源(比如:网络图片、本地文件)
        return new SourceGenerator(decodeHelper, this);
      case FINISHED:
        return null;
      default:
        throw new IllegalStateException("Unrecognized stage: " + stage);
    }
  }

 //这里开始加载执行
  private void runGenerators() {
    currentThread = Thread.currentThread();
    startFetchTime = LogTime.getLogTime();
    boolean isStarted = false;
    //这里Generator.startNext()方法中就是加载过程,如果成功加载则返回true并跳出循环,否则切换Generator继续执行。
    while (!isCancelled && currentGenerator != null
        && !(isStarted = currentGenerator.startNext())) {
      stage = getNextStage(stage);
      currentGenerator = getNextGenerator();

     //如果任务执行到去加载资源(也就是没有命中磁盘缓存),且切换任务执行环境
      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() {
    //更改执行目标为:SOURCE服务。当然也只有在stage == Stage.SOURCE的情况下会被调用。
    runReason = RunReason.SWITCH_TO_SOURCE_SERVICE;
    callback.reschedule(this);//这里callback正是EngineJob。
  } 
  
  //代码跟进EngineJob类中,可以看到实现方法。
  @Override
  public void reschedule(DecodeJob job) {
    // 可以看到,这里获取的SourceExecutor来执行decodeJob。
    //也就巧妙地将此decodeJob任务从cacheExecutor切换到了SourceExecutor,这样分工协作更加高效。
    getActiveSourceExecutor().execute(job);
  }
 

从最开始没有命中内存缓存开始,然后执行Engine的start方法,默认情况会获取到cacheExecutor执行器来执行decodeJob任务;继续decodeJob的run方法,因为RunReason==INITIALIZE,接着获取stage,默认会返回Stage.RESOURCE_CACHE,这时通过getNextGenerator就返回了ResourceCacheGenerator加载器,紧接着就是调用 ResourceCacheGenerator的startNext方法 ,从转换后的缓存中读取已缓存的资源,如果命中则结束任务并回调结果,反之,任务切换到DataCacheGenerator加载器继续执行,若还是未命中,则切换到SourceGenerator加载器(第一次加载,由于没有任何缓存,就会走到这里),这时会通过任务调度,将线程运行环境切换到 SourceExecutor执行器来执行,最后,待SourceGenerator加载完成后结束任务,回调结果,流程结束。


image

参考文章

https://www.jianshu.com/p/7c72e040087c

你可能感兴趣的:(Glide源码分析)