Glide源码分析之加载图片URL
2024-04-09 23:00:20  阅读数 877

简介

Glide 作为Android开发过程中常见的图片加载工具,在我们日常开发中用到到越来越多.但是个人也只是停留在用的状态.最近时间充裕简单的梳理了一下Glide 加载网络图的流程

流程

1.1 Glide.with(content) 得到RequestManagerRetriever初始化了RequestManager和Glide.

 @NonNull
public static RequestManager with(@NonNull Context context) {

 //etRetriever()  获取RequestManagerRetriever
 return getRetriever(context).get(context);
}


 @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)) {
   if (context instanceof FragmentActivity) {
     return get((FragmentActivity) context);
   } else if (context instanceof Activity) {
     return get((Activity) context);
   } else if (context instanceof ContextWrapper) {
     return get(((ContextWrapper) context).getBaseContext());
   }
 }

 return getApplicationManager(context);
}



Glide.with(context) --> (RequestManagerRetriever)getRetriever(context).get(context)-->
(RequestManagerRetriever)getApplicationManager(context){
    //初始化 Glide  
  Glide glide = Glide.get(context.getApplicationContext());
  
  //初始化 RequestManager
       applicationManager =
           factory.build(
               glide,
               new ApplicationLifecycle(),
               new EmptyRequestManagerTreeNode(),
               context.getApplicationContext());
     }
}


//创建 RequestManager
 public interface RequestManagerFactory {
 @NonNull
 RequestManager build(
     @NonNull Glide glide,
     @NonNull Lifecycle lifecycle,
     @NonNull RequestManagerTreeNode requestManagerTreeNode,
     @NonNull Context context);
}
//创建 RequestManager
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);
 }
};
}


1.2 Glide.get(context.getApplicationContext())


 Glide.get(context.getApplicationContext()) -->checkAndInitializeGlide(context)
 
-->initializeGlide(...)-->(GlideBuilder)builder.build(applicationContext)-->

public Glide build(@NonNull Context context) {
     //初始化 Glide
     ...
     
     //注意这个要用 初始化了 下边要用的 (RequestManagerFactory)factory
     RequestManagerRetriever requestManagerRetriever =new RequestManagerRetriever(requestManagerFactory);
     
     return new Glide(.....)
}

2.0 Glide.with(context).load() 的load方法

load()方法默认是 asRrawable()类型,用来初始化RequestBuilder 和 loadGeneric()方法初始化model(地址)

注意
这里体现了 asBitmap()和asDrawable() 方法必须放在load()前边的原因

//as方法
@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable String string) {
 return asDrawable().load(string);
}

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

//(重要) 创建了 RequestBuilder  且 默认传入的 resourceClass  是  Drawable.class)
//返回 获取target DrawableImageViewTarget
 @NonNull
@CheckResult
public <ResourceType> RequestBuilder<ResourceType> as(
   @NonNull Class<ResourceType> resourceClass) {
 return new RequestBuilder<>(glide, this, resourceClass, context);
}



//设置加载的内容(地址或者资源  )
 /**
* Sets the specific model to load data for.
*
* @param model The model to load data for, or null.
* @return This request builder.
*/
@NonNull
@CheckResult
@SuppressWarnings("unchecked")
@Override
public RequestBuilder<TranscodeType> load(@Nullable Object model) {
 return loadGeneric(model);
}

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


3.Glide 的into() 资源选择以及下载都在这里这里重点分析

1.调用into方法()

//调用into()方法

  @NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
  Util.assertMainThread();
  Preconditions.checkNotNull(view);
  //设置 RequestOptions 参数
  RequestOptions requestOptions = this.requestOptions;
  if (!requestOptions.isTransformationSet()
      && requestOptions.isTransformationAllowed()
      && view.getScaleType() != null) {
    // Clone in this method so that if we use this RequestBuilder to load into a View and then
    // into a different target, we don't retain the transformation applied based on the previous
    // View's scale type.
    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.
    }
  }
      //获取 ViewTarget 类型  默认得到DrawableImageViewTarget  因为load方法默认调用 asDrawable()
      glideContext.buildImageViewTarget(view, transcodeClass)
      
  return into(
      glideContext.buildImageViewTarget(view, transcodeClass),
      /*targetListener=*/ null,
      requestOptions);
}

//继续调用
  private <Y extends Target<TranscodeType>> Y into(
    @NonNull Y target,
    @Nullable RequestListener<TranscodeType> targetListener,
    @NonNull RequestOptions options) {
    //判断主线程
  Preconditions.checkNotNull(target);
  if (!isModelSet) {
    throw new IllegalArgumentException("You must call #load() before calling #into()");
  }

  options = options.autoClone();
  //构建请求  核心方法
  Request request = buildRequest(target, targetListener, options);

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

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

  return target;
}


1.2.构建请求(RequestBuilder 请求构建类)

//  调用构建请求RequestBuilder 的构建方法
private Request buildRequest(
    Target<TranscodeType> target,
    @Nullable RequestListener<TranscodeType> targetListener,
    RequestOptions requestOptions) {
  return buildRequestRecursive(
      target,
      targetListener,
      /*parentCoordinator=*/ null,
      transitionOptions,
      requestOptions.getPriority(),
      requestOptions.getOverrideWidth(),
      requestOptions.getOverrideHeight(),
      requestOptions);
}

private Request buildRequestRecursive(
    Target<TranscodeType> target,
    @Nullable RequestListener<TranscodeType> targetListener,
    @Nullable RequestCoordinator parentCoordinator,
    TransitionOptions<?, ? super TranscodeType> transitionOptions,
    Priority priority,
    int overrideWidth,
    int overrideHeight,
    RequestOptions requestOptions) {

  // Build the ErrorRequestCoordinator first if necessary so we can update parentCoordinator.
  ErrorRequestCoordinator errorRequestCoordinator = null;
  
  //判断错误的构建是否存在,这里第一次不执行
  if (errorBuilder != null) {
    errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
    parentCoordinator = errorRequestCoordinator;
  }

      //执行构建主要的请求
  Request mainRequest =
      buildThumbnailRequestRecursive(
          target,
          targetListener,
          parentCoordinator,
          transitionOptions,
          priority,
          overrideWidth,
          overrideHeight,
          requestOptions);

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

  int errorOverrideWidth = errorBuilder.requestOptions.getOverrideWidth();
  int errorOverrideHeight = errorBuilder.requestOptions.getOverrideHeight();
  if (Util.isValidDimensions(overrideWidth, overrideHeight)
      && !errorBuilder.requestOptions.isValidOverride()) {
    errorOverrideWidth = requestOptions.getOverrideWidth();
    errorOverrideHeight = requestOptions.getOverrideHeight();
  }

  Request errorRequest = errorBuilder.buildRequestRecursive(
      target,
      targetListener,
      errorRequestCoordinator,
      errorBuilder.transitionOptions,
      errorBuilder.requestOptions.getPriority(),
      errorOverrideWidth,
      errorOverrideHeight,
      errorBuilder.requestOptions);
  errorRequestCoordinator.setRequests(mainRequest, errorRequest);
  return errorRequestCoordinator;
}
  
  //执行构建主要的请求 
private Request buildThumbnailRequestRecursive(
    Target<TranscodeType> target,
    RequestListener<TranscodeType> targetListener,
    @Nullable RequestCoordinator parentCoordinator,
    TransitionOptions<?, ? super TranscodeType> transitionOptions,
    Priority priority,
    int overrideWidth,
    int overrideHeight,
    RequestOptions requestOptions) {
    //第一次为空
  if (thumbnailBuilder != null) {
    // Recursive case: contains a potentially recursive thumbnail request builder.
    if (isThumbnailBuilt) {
      throw new IllegalStateException("You cannot use a request as both the main request and a "
          + "thumbnail, consider using clone() on the request(s) passed to thumbnail()");
    }

    TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions =
        thumbnailBuilder.transitionOptions;

    // Apply our transition by default to thumbnail requests but avoid overriding custom options
    // that may have been applied on the thumbnail request explicitly.
    if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
      thumbTransitionOptions = transitionOptions;
    }

    Priority thumbPriority = thumbnailBuilder.requestOptions.isPrioritySet()
        ? thumbnailBuilder.requestOptions.getPriority() : getThumbnailPriority(priority);

    int thumbOverrideWidth = thumbnailBuilder.requestOptions.getOverrideWidth();
    int thumbOverrideHeight = thumbnailBuilder.requestOptions.getOverrideHeight();
    if (Util.isValidDimensions(overrideWidth, overrideHeight)
        && !thumbnailBuilder.requestOptions.isValidOverride()) {
      thumbOverrideWidth = requestOptions.getOverrideWidth();
      thumbOverrideHeight = requestOptions.getOverrideHeight();
    }

    ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
    Request fullRequest =
        obtainRequest(
            target,
            targetListener,
            requestOptions,
            coordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight);
    isThumbnailBuilt = true;
    // Recursively generate thumbnail requests.
    Request thumbRequest =
        thumbnailBuilder.buildRequestRecursive(
            target,
            targetListener,
            coordinator,
            thumbTransitionOptions,
            thumbPriority,
            thumbOverrideWidth,
            thumbOverrideHeight,
            thumbnailBuilder.requestOptions);
    isThumbnailBuilt = false;
    coordinator.setRequests(fullRequest, thumbRequest);
    return coordinator;
  } else if (thumbSizeMultiplier != null) {
    // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
    ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
    Request fullRequest =
        obtainRequest(
            target,
            targetListener,
            requestOptions,
            coordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight);
    RequestOptions thumbnailOptions = requestOptions.clone()
        .sizeMultiplier(thumbSizeMultiplier);

    Request thumbnailRequest =
        obtainRequest(
            target,
            targetListener,
            thumbnailOptions,
            coordinator,
            transitionOptions,
            getThumbnailPriority(priority),
            overrideWidth,
            overrideHeight);

    coordinator.setRequests(fullRequest, thumbnailRequest);
    return coordinator;
  } else {
    // Base case: no thumbnail.
    
    // 第一次为空直接执行
    return obtainRequest(
        target,
        targetListener,
        requestOptions,
        parentCoordinator,
        transitionOptions,
        priority,
        overrideWidth,
        overrideHeight);
  }
}
  //获取请求
private Request obtainRequest(
    Target<TranscodeType> target,
    RequestListener<TranscodeType> targetListener,
    RequestOptions requestOptions,
    RequestCoordinator requestCoordinator,
    TransitionOptions<?, ? super TranscodeType> transitionOptions,
    Priority priority,
    int overrideWidth,
    int overrideHeight) {
  return SingleRequest.obtain(
      context,
      glideContext,
      model,
      transcodeClass,
      requestOptions,
      overrideWidth,
      overrideHeight,
      priority,
      target,
      targetListener,
      requestListener,
      requestCoordinator,
      glideContext.getEngine(),
      transitionOptions.getTransitionFactory());
}


// SingleRequest 单例请求类


  public static <R> SingleRequest<R> obtain(
    Context context,
    GlideContext glideContext,
    Object model,
    Class<R> transcodeClass,
    RequestOptions requestOptions,
    int overrideWidth,
    int overrideHeight,
    Priority priority,
    Target<R> target,
    RequestListener<R> targetListener,
    RequestListener<R> requestListener,
    RequestCoordinator requestCoordinator,
    Engine engine,
    TransitionFactory<? super R> animationFactory) {
  @SuppressWarnings("unchecked") SingleRequest<R> request =
      (SingleRequest<R>) POOL.acquire();
  if (request == null) {
    request = new SingleRequest<>();
  }
  request.init(
      context,
      glideContext,
      model,
      transcodeClass,
      requestOptions,
      overrideWidth,
      overrideHeight,
      priority,
      target,
      targetListener,
      requestListener,
      requestCoordinator,
      engine,
      animationFactory);
  return request;
}

//初始化单例 请求
rivate void init(
    Context context,
    GlideContext glideContext,
    Object model,
    Class<R> transcodeClass,
    RequestOptions requestOptions,
    int overrideWidth,
    int overrideHeight,
    Priority priority,
    Target<R> target,
    RequestListener<R> targetListener,
    RequestListener<R> requestListener,
    RequestCoordinator requestCoordinator,
    Engine engine,
    TransitionFactory<? super R> animationFactory) {
  this.context = context;
  this.glideContext = glideContext;
  this.model = model;
  this.transcodeClass = transcodeClass;
  this.requestOptions = requestOptions;
  this.overrideWidth = overrideWidth;
  this.overrideHeight = overrideHeight;
  this.priority = priority;
  this.target = target;
  this.targetListener = targetListener;
  this.requestListener = requestListener;
  this.requestCoordinator = requestCoordinator;
  this.engine = engine;
  this.animationFactory = animationFactory;
  status = Status.PENDING;
}

1.3 开启请求



  private <Y extends Target<TranscodeType>> Y into(
    @NonNull Y target,
    @Nullable RequestListener<TranscodeType> targetListener,
    @NonNull RequestOptions options) {
    //判断主线程
  Preconditions.checkNotNull(target);
  if (!isModelSet) {
    throw new IllegalArgumentException("You must call #load() before calling #into()");
  }

  options = options.autoClone();
  //构建请求  只是做了个初始化的操作  
  Request request = buildRequest(target, targetListener, options);
     //  返回这个Target 上边的请求  因为上边是做初始化操作所以 第一次这个previous 请求是null
     //  request.isEquivalentTo(previous)  =false
  Request previous = target.getRequest();
  if (request.isEquivalentTo(previous)
      && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
    request.recycle();
   
    if (!Preconditions.checkNotNull(previous).isRunning()) {
     //开启请求
      previous.begin();
    }
    return target;
  }

  requestManager.clear(target);
  //给target设置上请求
  target.setRequest(request);
  //开启 请求(正常情况下走这个)
  requestManager.track(target, request);

  return target;
}


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


public void runRequest(Request request) {
  requests.add(request);
  // 我的Demo是在 Activity 中展示所以isPaused()是true 所以是否执行请求是根据生命周期走的
  
  if (!isPaused) {
    request.begin();
  } else {
    pendingRequests.add(request);
  }
}


查了一下代码 因为  RequestManager 实现了 LifecycleListener 监听了页面的生命周期 所以 

RequestManager中实现了 onStart 方法 resumeRequests 调用了resumeRequests()
@Override
public void onStart() {
  resumeRequests();
  targetTracker.onStart();
}


 //页面展示开启请求
public void resumeRequests() {
  isPaused = false;
  for (Request request : Util.getSnapshot(requests)) {
    if (!request.isComplete() && !request.isCancelled() && !request.isRunning()) {
      request.begin();
    }
  }
  pendingRequests.clear();
}

//上边是请求执行了

1.4 SingleRequest 单例请求的代码


public static <R> SingleRequest<R> obtain(
    Context context,
    GlideContext glideContext,
    Object model,
    Class<R> transcodeClass,
    RequestOptions requestOptions,
    int overrideWidth,
    int overrideHeight,
    Priority priority,
    Target<R> target,
    RequestListener<R> targetListener,
    RequestListener<R> requestListener,
    RequestCoordinator requestCoordinator,
    Engine engine,
    TransitionFactory<? super R> animationFactory) {
  @SuppressWarnings("unchecked") SingleRequest<R> request =
      (SingleRequest<R>) POOL.acquire();
  if (request == null) {
    request = new SingleRequest<>();
  }
  request.init(
      context,
      glideContext,
      model,
      transcodeClass,
      requestOptions,
      overrideWidth,
      overrideHeight,
      priority,
      target,
      targetListener,
      requestListener,
      requestCoordinator,
      engine,
      animationFactory);
  return request;
}

@SuppressWarnings("WeakerAccess")
@Synthetic
SingleRequest() {
  // just create, instances are reused with recycle/init
}
//初始化了请求的数据
private void init(
    Context context,
    GlideContext glideContext,
    Object model,
    Class<R> transcodeClass,
    RequestOptions requestOptions,
    int overrideWidth,
    int overrideHeight,
    Priority priority,
    Target<R> target,
    RequestListener<R> targetListener,
    RequestListener<R> requestListener,
    RequestCoordinator requestCoordinator,
    Engine engine,
    TransitionFactory<? super R> animationFactory) {
  this.context = context;
  this.glideContext = glideContext;
  this.model = model;
  this.transcodeClass = transcodeClass;
  this.requestOptions = requestOptions;
  this.overrideWidth = overrideWidth;
  this.overrideHeight = overrideHeight;
  this.priority = priority;
  this.target = target;
  this.targetListener = targetListener;
  this.requestListener = requestListener;
  this.requestCoordinator = requestCoordinator;
  this.engine = engine;
  this.animationFactory = animationFactory;
  status = Status.PENDING;
}


//开启了请求
  @Override
public void begin() {
  assertNotCallingCallbacks();
  stateVerifier.throwIfRecycled();
  startTime = LogTime.getLogTime();
  // model 就是load() 传入的地址或者资源数据 为空直接走了 错误的回调然后直接返回
  if (model == null) {
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      width = overrideWidth;
      height = overrideHeight;
    }
    
    onLoadFailed(new GlideException("Received null model"), logLevel);
    return;
  }

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

  //加载完成状态
  if (status == Status.COMPLETE) {
    onResourceReady(resource, DataSource.MEMORY_CACHE);
    return;
  }

  // Restarts for requests that are neither complete nor running can be treated as new requests
  // and can run again from the beginning.

  status = Status.WAITING_FOR_SIZE;
  // 判断图片的宽高  有宽高证明存在直接展示
  if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
    onSizeReady(overrideWidth, overrideHeight);
  } else {
  //重要 执行了获取宽高的方法  因为实现了SizeReadyCallback接口 执行  onSizeReady() 方法
  
  //DrawableImageViewTarget --> ViewTarget --> getSize(SizeReadyCallback cb)
       //{      cb.onSizeReady(currentWidth, currentHeight);}
      
  target.getSize(this);
  }

  if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
      && canNotifyStatusChanged()) {
      //开始加载  getPlaceholderDrawable() 获取占位图
    target.onLoadStarted(getPlaceholderDrawable());
  }
  if (IS_VERBOSE_LOGGABLE) {
    logV("finished run method in " + LogTime.getElapsedMillis(startTime));
  }
}


1.5 Engine 下载图片


  @Override
public void onSizeReady(int width, int height) {
  stateVerifier.throwIfRecycled();
  if (IS_VERBOSE_LOGGABLE) {
    logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
  }
  if (status != Status.WAITING_FOR_SIZE) {
    return;
  }
  status = Status.RUNNING;

  float sizeMultiplier = requestOptions.getSizeMultiplier();
  this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
  this.height = maybeApplySizeMultiplier(height, sizeMultiplier);

  if (IS_VERBOSE_LOGGABLE) {
    logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
  }
  
 //  Engine  负责启动负载并管理活动和缓存的资源 
 // 加载资源     监听是 ResourceCallback  实现方法 onResourceReady  加载准备
  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);

  // This is a hack that's only useful for testing right now where loads complete synchronously
  // even though under any executor running on any thread but the main thread, the load would
  // have completed asynchronously.
  if (status != Status.RUNNING) {
    loadStatus = null;
  }
  if (IS_VERBOSE_LOGGABLE) {
    logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
  }


//  Engine  负责启动负载并管理活动和缓存的资源

  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) {
  Util.assertMainThread();
  long startTime = LogTime.getLogTime();

  EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
      resourceClass, transcodeClass, options);
  //从活动资源加载资源
  EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
  if (active != null) {
    cb.onResourceReady(active, DataSource.MEMORY_CACHE);
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey("Loaded resource from active resources", startTime, key);
    }
    return null;
  }
//加载缓存资源
  EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
  if (cached != null) {
    cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey("Loaded resource from cache", startTime, key);
    }
    return null;
  }
  //当前加载网络资源 (同请求加载重新请求的资源))
  EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
  if (current != null) {
    current.addCallback(cb);
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey("Added to existing load", startTime, key);
    }
    return new LoadStatus(cb, current);
  }

  EngineJob<R> engineJob =
      engineJobFactory.build(
          key,
          isMemoryCacheable,
          useUnlimitedSourceExecutorPool,
          useAnimationPool,
          onlyRetrieveFromCache);

  DecodeJob<R> decodeJob =
      decodeJobFactory.build(
          glideContext,
          model,
          key,
          signature,
          width,
          height,
          resourceClass,
          transcodeClass,
          priority,
          diskCacheStrategy,
          transformations,
          isTransformationRequired,
          isScaleOnlyOrNoTransform,
          onlyRetrieveFromCache,
          options,
          engineJob);

  jobs.put(key, engineJob);
      //增加监听
  engineJob.addCallback(cb);
  //启动加载
  engineJob.start(decodeJob);

  if (Log.isLoggable(TAG, Log.VERBOSE)) {
    logWithTimeAndKey("Started new load", startTime, key);
  }
  return new LoadStatus(cb, engineJob);
}
// 开启异步加载数据
  public void start(DecodeJob<R> decodeJob) {
  this.decodeJob = decodeJob;
  GlideExecutor executor = decodeJob.willDecodeFromCache()
      ? diskCacheExecutor
      : getActiveSourceExecutor();
      //开始加载
  executor.execute(decodeJob);
}
 


1.6 DecodeJob下载的线程(重要)

 @Override
public void run() {

  TraceCompat.beginSection("DecodeJob#run");
  
  DataFetcher<?> localFetcher = currentFetcher;
  try {
  //是否取消请求
    if (isCancelled) {
      notifyFailed();
      return;
    }
    //运行
    runWrapped();
  } catch (Throwable t) {
    // Catch Throwable and not Exception to handle OOMs. Throwables are swallowed by our
    // usage of .submit() in GlideExecutor so we're not silently hiding crashes by doing this. We
    // are however ensuring that our callbacks are always notified when a load fails. Without this
    // notification, uncaught throwables never notify the corresponding callbacks, which can cause
    // loads to silently hang forever, a case that's especially bad for users using Futures on
    // background threads.
    if (Log.isLoggable(TAG, Log.DEBUG)) {
      Log.d(TAG, "DecodeJob threw unexpectedly"
          + ", isCancelled: " + isCancelled
          + ", stage: " + stage, t);
    }
    // When we're encoding we've already notified our callback and it isn't safe to do so again.
    if (stage != Stage.ENCODE) {
      throwables.add(t);
      notifyFailed();
    }
    if (!isCancelled) {
      throw t;
    }
  } finally {
    // Keeping track of the fetcher here and calling cleanup is excessively paranoid, we call
    // close in all cases anyway.
    if (localFetcher != null) {
      localFetcher.cleanup();
    }
    TraceCompat.endSection();
  }
}
  //运行选择的处理()会循环执行 去判断三级资源 先资源判断 再缓存半段 再下载
private void runWrapped() {
   switch (runReason) {
   // The first time we've been submitted.  第一次请求
    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 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);
  }
}

//执行 数据判断(会循环上掉直到找到数据)  HttpUrlFetcher  没缓存走下载  
  private void runGenerators() {
  currentThread = Thread.currentThread();
  startFetchTime = LogTime.getLogTime();
  boolean isStarted = false;
  //currentGenerator.startNext() 执行找数据
  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 boolean startNext() {
  if (dataToCache != null) {
    Object data = dataToCache;
    dataToCache = null;
    cacheData(data);
  }

  if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
    return true;
  }
  sourceCacheGenerator = null;

  loadData = null;
  boolean started = false;
  while (!started && hasNextModelLoader()) {
    loadData = helper.getLoadData().get(loadDataListIndex++);
    if (loadData != null
        && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
        || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
      started = true;
      loadData.fetcher.loadData(helper.getPriority(), this);
    }
  }
  return started;
}




1.7 下载\


  //HttpUrlFetcher 
   //* A DataFetcher that retrieves an {@link java.io.InputStream} for a Url.



 @Override
  public boolean startNext() {
    if (dataToCache != null) {
      Object data = dataToCache;
      dataToCache = null;
      cacheData(data);
    }

    if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
      return true;
    }
    sourceCacheGenerator = null;

    loadData = null;
    boolean started = false;
    while (!started && hasNextModelLoader()) {
      loadData = helper.getLoadData().get(loadDataListIndex++);
      if (loadData != null
          && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
          || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
        started = true;
        loadData.fetcher.loadData(helper.getPriority(), this);
      }
    }
    return started;
  }
  
  
  //  图片下载
  
  
  @Override
  public void loadData(@NonNull Priority priority,
      @NonNull DataCallback<? super InputStream> callback) {
    long startTime = LogTime.getLogTime();
    try {
 // callback SourceGenerator 实现了  DataFetcher.DataCallback<Object> 接口  回调到 SourceGenerator
    
      InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
      callback.onDataReady(result);
    } catch (IOException e) {
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "Failed to load data for url", e);
      }
      //FetcherReadyCallback  下载回调
      callback.onLoadFailed(e);
    } finally {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Finished http url fetcher fetch in " + LogTime.getElapsedMillis(startTime));
      }
    }
  }

  private InputStream loadDataWithRedirects(URL url, int redirects, URL lastUrl,
      Map<String, String> headers) throws IOException {
    if (redirects >= MAXIMUM_REDIRECTS) {
      throw new HttpException("Too many (> " + MAXIMUM_REDIRECTS + ") redirects!");
    } else {
      // Comparing the URLs using .equals performs additional network I/O and is generally broken.
      // See http://michaelscharf.blogspot.com/2006/11/javaneturlequals-and-hashcode-make.html.
      try {
        if (lastUrl != null && url.toURI().equals(lastUrl.toURI())) {
          throw new HttpException("In re-direct loop");

        }
      } catch (URISyntaxException e) {
        // Do nothing, this is best effort.
      }
    }

    urlConnection = connectionFactory.build(url);
    for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
      urlConnection.addRequestProperty(headerEntry.getKey(), headerEntry.getValue());
    }
    urlConnection.setConnectTimeout(timeout);
    urlConnection.setReadTimeout(timeout);
    urlConnection.setUseCaches(false);
    urlConnection.setDoInput(true);

    // Stop the urlConnection instance of HttpUrlConnection from following redirects so that
    // redirects will be handled by recursive calls to this method, loadDataWithRedirects.
    urlConnection.setInstanceFollowRedirects(false);

    // Connect explicitly to avoid errors in decoders if connection fails.
    urlConnection.connect();
    // Set the stream so that it's closed in cleanup to avoid resource leaks. See #2352.
    stream = urlConnection.getInputStream();
    if (isCancelled) {
      return null;
    }
    final int statusCode = urlConnection.getResponseCode();
    if (isHttpOk(statusCode)) {
      return getStreamForSuccessfulRequest(urlConnection);
    } else if (isHttpRedirect(statusCode)) {
      String redirectUrlString = urlConnection.getHeaderField("Location");
      if (TextUtils.isEmpty(redirectUrlString)) {
        throw new HttpException("Received empty or null redirect url");
      }
      URL redirectUrl = new URL(url, redirectUrlString);
      // Closing the stream specifically is required to avoid leaking ResponseBodys in addition
      // to disconnecting the url connection below. See #2352.
      cleanup();
      return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
    } else if (statusCode == INVALID_STATUS_CODE) {
      throw new HttpException(statusCode);
    } else {
      throw new HttpException(urlConnection.getResponseMessage(), statusCode);
    }
  }
  

1.8 回调

    // 的回调到  SourceGenerator  onDataReady
  @Override
  public void onDataReady(Object data) {
    DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
    if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
      dataToCache = data;
      // We might be being called back on someone else's thread. Before doing anything, we should
      // reschedule to get back onto Glide's thread.
      cb.reschedule();
    } else {
      cb.onDataFetcherReady(loadData.sourceKey, data, loadData.fetcher,
          loadData.fetcher.getDataSource(), originalKey);
    }
  }
  
  
  
  
   // 因为  DecodeJob 实现了   FetcherReadyCallback 接口 且 SourceGenerator(this)  是这么创建的 
 //所以回调到 DecodeJob  的  onDataFetcherReady方法

    @Override
  public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
      DataSource dataSource, Key attemptedKey) {
    // This data fetcher will be loading from a File and provide the wrong data source, so override
    // with the data source of the original fetcher
    // cb  是 DecodeJob
    cb.onDataFetcherReady(sourceKey, data, fetcher, loadData.fetcher.getDataSource(), sourceKey);
  }
  

    //  DecodeJob  的 onDataFetcherReady
    @Override
  public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
      DataSource dataSource, Key attemptedKey) {
    this.currentSourceKey = sourceKey;
    this.currentData = data;
    this.currentFetcher = fetcher;
    this.currentDataSource = dataSource;
    this.currentAttemptingKey = attemptedKey;
    if (Thread.currentThread() != currentThread) {
      runReason = RunReason.DECODE_DATA;
      callback.reschedule(this);
    } else {
      TraceCompat.beginSection("DecodeJob.decodeFromRetrievedData");
      try {
      //数解码(处理下载的数据)
        decodeFromRetrievedData();
      } finally {
        TraceCompat.endSection();
      }
    }
  }
  
  
    private void decodeFromRetrievedData() {
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey("Retrieved data", startFetchTime,
          "data: " + currentData
          + ", cache key: " + currentSourceKey
          + ", fetcher: " + currentFetcher);
    }
    Resource<R> resource = null;
    try {
      resource = decodeFromData(currentFetcher, currentData, currentDataSource);
    } catch (GlideException e) {
      e.setLoggingDetails(currentAttemptingKey, currentDataSource);
      throwables.add(e);
    }
    if (resource != null) {
      notifyEncodeAndRelease(resource, currentDataSource);
    } else {
      runGenerators();
    }
  }
  
  //通知
  private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
    if (resource instanceof Initializable) {
      ((Initializable) resource).initialize();
    }

    Resource<R> result = resource;
    LockedResource<R> lockedResource = null;
    if (deferredEncodeManager.hasResourceToEncode()) {
      lockedResource = LockedResource.obtain(resource);
      result = lockedResource;
    }
     //下载完成通知填充页面
    notifyComplete(result, dataSource);

    stage = Stage.ENCODE;
    try {
      if (deferredEncodeManager.hasResourceToEncode()) {
        deferredEncodeManager.encode(diskCacheProvider, options);
      }
    } finally {
      if (lockedResource != null) {
        lockedResource.unlock();
      }
    }
    // Call onEncodeComplete outside the finally block so that it's not called if the encode process
    // throws.
    onEncodeComplete();
  }
  
  
  private void notifyComplete(Resource<R> resource, DataSource dataSource) {
    setNotifiedOrThrow();
    
   // callback 是传入的调用EngineJob  调用 EngineJob的onResourceReady方法  
    callback.onResourceReady(resource, dataSource);
  }



//EngineJob的onResourceReady()方法
//发完成的通知
  @Override
  public void onResourceReady(Resource<R> resource, DataSource dataSource) {
    this.resource = resource;
    this.dataSource = dataSource;
    MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
  }

//状态的Handler 

private static final Handler MAIN_THREAD_HANDLER =
      new Handler(Looper.getMainLooper(), new MainThreadCallback());
  
  
  private static class MainThreadCallback implements Handler.Callback {

    @Synthetic
    @SuppressWarnings("WeakerAccess")
    MainThreadCallback() { }

    @Override
    public boolean handleMessage(Message message) {
      EngineJob<?> job = (EngineJob<?>) message.obj;
      switch (message.what) {
        case MSG_COMPLETE:
        //完成的的通知
          job.handleResultOnMainThread();
          break;
        case MSG_EXCEPTION:
          job.handleExceptionOnMainThread();
          break;
        case MSG_CANCELLED:
          job.handleCancelledOnMainThread();
          break;
        default:
          throw new IllegalStateException("Unrecognized message: " + message.what);
      }
      return true;
    }
  }
  
  
  
  
    @Synthetic
  void handleResultOnMainThread() {
    stateVerifier.throwIfRecycled();
    if (isCancelled) {
      resource.recycle();
      release(false /*isRemovedFromQueue*/);
      return;
    } else if (cbs.isEmpty()) {
      throw new IllegalStateException("Received a resource without any callbacks to notify");
    } else if (hasResource) {
      throw new IllegalStateException("Already have resource");
    }
    engineResource = engineResourceFactory.build(resource, isCacheable);
    hasResource = true;

    // Hold on to resource for duration of request so we don't recycle it in the middle of
    // notifying if it synchronously released by one of the callbacks.
    engineResource.acquire();
    listener.onEngineJobComplete(this, key, engineResource);

    //noinspection ForLoopReplaceableByForEach to improve perf
    for (int i = 0, size = cbs.size(); i < size; i++) {
      ResourceCallback cb = cbs.get(i);
      if (!isInIgnoredCallbacks(cb)) {
        engineResource.acquire();
        //cb是 SingleRequest    回调的单例请求onResourceReady 的方法
        cb.onResourceReady(engineResource, dataSource);
      }
    }
    // Our request is complete, so we can release the resource.
    engineResource.release();

    release(false /*isRemovedFromQueue*/);
  }
  
  // SingleRequest 单例请求
  
    /**
   * A callback method that should never be invoked directly.
   */
  @SuppressWarnings("unchecked")
  @Override
  public void onResourceReady(Resource<?> resource, DataSource dataSource) {
    stateVerifier.throwIfRecycled();
    loadStatus = null;
    if (resource == null) {
      GlideException exception = new GlideException("Expected to receive a Resource<R> with an "
          + "object of " + transcodeClass + " inside, but instead got null.");
      onLoadFailed(exception);
      return;
    }

    Object received = resource.get();
    if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
      releaseResource(resource);
      GlideException exception = new GlideException("Expected to receive an object of "
          + transcodeClass + " but instead" + " got "
          + (received != null ? received.getClass() : "") + "{" + received + "} inside" + " "
          + "Resource{" + resource + "}."
          + (received != null ? "" : " " + "To indicate failure return a null Resource "
          + "object, rather than a Resource object containing null data."));
      onLoadFailed(exception);
      return;
    }

    if (!canSetResource()) {
      releaseResource(resource);
      // We can't put the status to complete before asking canSetResource().
      status = Status.COMPLETE;
      return;
    }
    //资源准备好了 
    onResourceReady((Resource<R>) resource, (R) received, dataSource);
  }

  /**
   * Internal {@link #onResourceReady(Resource, DataSource)} where arguments are known to be safe.
   *
   * @param resource original {@link Resource}, never <code>null</code>
   * @param result   object returned by {@link Resource#get()}, checked for type and never
   *                 <code>null</code>
   */
  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;

    if (glideContext.getLogLevel() <= Log.DEBUG) {
      Log.d(GLIDE_TAG, "Finished loading " + result.getClass().getSimpleName() + " from "
          + dataSource + " for " + model + " with size [" + width + "x" + height + "] in "
          + LogTime.getElapsedMillis(startTime) + " ms");
    }

    isCallingCallbacks = true;
    try {
      if ((requestListener == null
          || !requestListener.onResourceReady(result, model, target, dataSource, isFirstResource))
          && (targetListener == null
          || !targetListener.onResourceReady(result, model, target, dataSource, isFirstResource))) {
        Transition<? super R> animation =
            animationFactory.build(dataSource, isFirstResource);
            //填充到页面 target 默认是DrawableImageViewTarget
        target.onResourceReady(result, animation);
      }
    } finally {
      isCallingCallbacks = false;
    }

    notifyLoadSuccess();
  }
  
  //最后回调到DrawableImageViewTarget 的setResource() 方法  view是个ImagView
   @Override
  protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);
  }

  
  

总结

这里简单的梳理了Glide 第一次加载图片 从初始化到配置参数,然后判断是否有缓存再到下载完成然后通知展示的简单流程.源码中涉及到的回调比较多建议代码跟一下(特别注意生命周期的影响).

大致上代码流程是:
Glide.with()配置Glide 的一些参数 load() 配置请求的构建起 into()首先判断本子资源是否有然后缓存文件是否存在都没有就调用下载,下载完成通知展示.因为Glide RequestManager implements LifecycleListener 监听了页面的生命周期注意,一下生命周期对展示的影响

还有一些生命周期对Glide的影响,以及异常展示的流程没有处理,有兴趣的可以研究下