Glide源码(二)

接着上一篇,with方法获取到RequestManager 对象,它实现了LifecycleListener接口,这意味着,页面生命周期的触发会通知到RequestManager 类,但根据上一篇分析,在此之前,它必须先被添加到ActivityFragmentLifecycle的成员变量lifecycleListeners 集合中 ,我们先看它的构造方法。

public class RequestManager implements LifecycleListener,
    ModelTypes> {

  private final ConnectivityMonitor connectivityMonitor;
  private final Handler mainHandler = new Handler(Looper.getMainLooper());
  private final CopyOnWriteArrayList> defaultRequestListeners;
  
  private final Runnable addSelfToLifecycle = new Runnable() {
    @Override
    public void run() {
      lifecycle.addListener(RequestManager.this);
    }
  };
  public RequestManager(
      @NonNull Glide glide, @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
    this(
        glide,
        lifecycle,
        treeNode,
        new RequestTracker(),
        glide.getConnectivityMonitorFactory(),
        context);
  }

  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;
    //网络监听器
    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));

    //后台线程,切到主线程中添加
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      //添加自己到ActivityFragmentLifecycle的集合中
      lifecycle.addListener(this);
    }
    //添加网络监听器
    lifecycle.addListener(connectivityMonitor);

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

    //保存到glide的成员列表中
    glide.registerRequestManager(this);
  }

}

可以看出,ConnectivityMonitor 也实现了LifecycleListener接口,因为它也被添加到lifecycleListeners 集合中,跟随Framgent的生命周期回调。

获取到RequestManager对象后,将调用load方法。

public class RequestManager implements LifecycleListener,
    ModelTypes> {

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

    public RequestBuilder load(@Nullable Drawable drawable) {
      return asDrawable().load(drawable);
    }

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

    //转码后的类型为Bitmap.class
    public RequestBuilder asBitmap() {
      return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
    }

    //转码后的类型为Drawable.class
    public RequestBuilder asDrawable() {
      return as(Drawable.class);
    }

    //获取RequestBuilder
    public  RequestBuilder as(
    @NonNull Class resourceClass) {
    // resourceClass 就是最终要转码的类型
      return new RequestBuilder<>(glide, this, resourceClass, context);
    }

}

适配不同资源的加载,load有多个重载方法,他们最终都通过as方法来获取一个RequestBuilder对象,后面一连串的链式调用,都将通过这个对象的方法作为入口来执行。和RequestManager 的load方法一样,RequestBuilder的load也有许多重载方法,我们以网络地址加载为例来做分析。

public class RequestBuilder extends BaseRequestOptions>
    implements Cloneable,
    ModelTypes> {

  private Object model;
  private boolean isModelSet;

  //加载网络地址
  public RequestBuilder load(@Nullable String string) {
      return loadGeneric(string);
    }

  //将地址封装成model
  private RequestBuilder loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
  }


}

在执行请求前,所有数据源都会被封装成一个model对象,它是Object类型的。

load方法调用完成,便获得的一个RequestBuilder对象,接着通过它调用into方法。

public class RequestBuilder extends BaseRequestOptions>
    implements Cloneable,
    ModelTypes> {

    ......

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

    BaseRequestOptions requestOptions = this;
    if (!requestOptions.isTransformationSet()
        && requestOptions.isTransformationAllowed()
        && view.getScaleType() != null) {
      // 根据裁剪配置options
      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:
      }
    }
  
    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        null,
        requestOptions,
        Executors.mainThreadExecutor());
      }

}

会根据我们在ImageView中设置的ScaleType类型,给requestOptions 配置裁剪类型。最后的into重载方法中,将调用buildImageViewTarget根据转码的类型来生成一个 ViewTarget,这个方法定义在GlideContext中。

public class GlideContext extends ContextWrapper {
      ......
  private final ImageViewTargetFactory imageViewTargetFactory;
     ......

  public  ViewTarget buildImageViewTarget(
      @NonNull ImageView imageView, @NonNull Class transcodeClass) {
    return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
  }

}

在上一篇分析Glide的初始化时,ImageViewTargetFactory 这个图片显示目标对象工厂,已经在构造方法中创建出来了,同时还创建了GlideContext 对象,将ImageViewTargetFactory 传递给它。

public class ImageViewTargetFactory {
  @NonNull
  @SuppressWarnings("unchecked")
  public  ViewTarget buildTarget(@NonNull ImageView view,
      @NonNull Class clazz) {
    //Bitmap
    if (Bitmap.class.equals(clazz)) {
      return (ViewTarget) new BitmapImageViewTarget(view);
    //是否Drawable或其子类
    } else if (Drawable.class.isAssignableFrom(clazz)) {
      return (ViewTarget) new DrawableImageViewTarget(view);
    } else {
      throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
  }
}

ViewTarget的子类有两种,在上面的RequestManager 类中虽然有多个as方法,但最终的转码类型只会有两类,即Bitmap类型或Drawable及其子类类型,我们加载网络地址,这里的ViewTarget将使用DrawableImageViewTarget,它继承ImageViewTarget,持有ImageView对象。

public class DrawableImageViewTarget extends ImageViewTarget {
  public DrawableImageViewTarget(ImageView view) {
    super(view);
  }

  @SuppressWarnings({"unused", "deprecation"})
  @Deprecated
  public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }

  //设置图片
  @Override
  protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);
  }
}

看到setResource这个方法我们可以猜到,最终图片被显示到ImageView中,将通过它来完成。我们先回到RequestManager 重载的into方法。

public class RequestBuilder extends BaseRequestOptions>
    implements Cloneable,
    ModelTypes> {


  private > Y into(
      @NonNull Y target,
      @Nullable RequestListener targetListener,
      BaseRequestOptions options,
      Executor callbackExecutor) {
  
    //这里的Target就是DrawableImageViewTarget了
    Preconditions.checkNotNull(target);

    //是否设置了数据源,也就是url,在load中isModelSet已置为true
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

    //Request类是一个接口,他抽象了Glide加载图片请求
    Request request = buildRequest(target, targetListener, options, callbackExecutor);
    //获取上一次的Request
    Request previous = target.getRequest();

    // 当前的target里有Request存在
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      //回收刚新建的Request对象
      request.recycle();
      if (!Preconditions.checkNotNull(previous).isRunning()) {
              //执行当前的Request
              previous.begin();
      }
      //结束
      return target;
    }
    //清除target
    requestManager.clear(target);
    //Target中设置request
    target.setRequest(request);
    //执行request
    requestManager.track(target, request);

    return target;
  }
}

Request用来发出加载图片的请求,通过buildRequest来构建,然后将通过RequestManager对象来执行这个请求。我们先看构建过程。

public class RequestBuilder extends BaseRequestOptions>
    implements Cloneable,
    ModelTypes> {


    private Request buildRequest(
      Target target,
      @Nullable RequestListener targetListener,
      BaseRequestOptions requestOptions,
      Executor callbackExecutor) {
    return buildRequestRecursive(
        target,
        targetListener,
         null,
        transitionOptions,
        requestOptions.getPriority(),
        requestOptions.getOverrideWidth(),
        requestOptions.getOverrideHeight(),
        requestOptions,
        callbackExecutor);
    }


    private Request buildRequestRecursive(
      Target target,
      @Nullable RequestListener targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions requestOptions,
      Executor callbackExecutor) {

    // 如果配置了错误请求则新建错误请求协调器
    ErrorRequestCoordinator errorRequestCoordinator = null;
    if (errorBuilder != null) {
      errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
      parentCoordinator = errorRequestCoordinator;
    }

  // 构造目标请求
    Request mainRequest =
        buildThumbnailRequestRecursive(
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions,
            callbackExecutor);

    //如果没有配置错误请求则结束,否则继续下面代码构建错误时的备用请求
    if (errorRequestCoordinator == null) {
      return mainRequest;
    }

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

  // 错误时的备用请求
    Request errorRequest =
        errorBuilder.buildRequestRecursive(
            target,
            targetListener,
            errorRequestCoordinator,
            errorBuilder.transitionOptions,
            errorBuilder.getPriority(),
            errorOverrideWidth,
            errorOverrideHeight,
            errorBuilder,
            callbackExecutor);
    errorRequestCoordinator.setRequests(mainRequest, errorRequest);
    return errorRequestCoordinator;
  }


    private Request buildThumbnailRequestRecursive(
      Target target,
      RequestListener targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions requestOptions,
      Executor callbackExecutor) {
 
    if (thumbnailBuilder != null) {
          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
      TransitionOptions thumbTransitionOptions =
          thumbnailBuilder.transitionOptions;

      if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
        thumbTransitionOptions = transitionOptions;
      }

      //优先级
      Priority thumbPriority = thumbnailBuilder.isPrioritySet()
          ? thumbnailBuilder.getPriority() : getThumbnailPriority(priority);

      //图片尺寸
      int thumbOverrideWidth = thumbnailBuilder.getOverrideWidth();
      int thumbOverrideHeight = thumbnailBuilder.getOverrideHeight();
      if (Util.isValidDimensions(overrideWidth, overrideHeight)
          && !thumbnailBuilder.isValidOverride()) {
        thumbOverrideWidth = requestOptions.getOverrideWidth();
        thumbOverrideHeight = requestOptions.getOverrideHeight();
      }
      
      // 缩略图请求协调器
      ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);

      // 目标请求
      Request fullRequest =
          obtainRequest(
              target,
              targetListener,
              requestOptions,
              coordinator,
              transitionOptions,
              priority,
              overrideWidth,
              overrideHeight,
              callbackExecutor);
      isThumbnailBuilt = true;

      // 缩略图的请求 
      Request thumbRequest =
          thumbnailBuilder.buildRequestRecursive(
              target,
              targetListener,
              coordinator,
              thumbTransitionOptions,
              thumbPriority,
              thumbOverrideWidth,
              thumbOverrideHeight,
              thumbnailBuilder,
              callbackExecutor);
      isThumbnailBuilt = false;
      coordinator.setRequests(fullRequest, thumbRequest);
      return coordinator;
    } else if (thumbSizeMultiplier != null) {
      ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
      Request fullRequest =
          obtainRequest(
              target,
              targetListener,
              requestOptions,
              coordinator,
              transitionOptions,
              priority,
              overrideWidth,
              overrideHeight,
              callbackExecutor);
      BaseRequestOptions thumbnailOptions =
          requestOptions.clone().sizeMultiplier(thumbSizeMultiplier);

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

      coordinator.setRequests(fullRequest, thumbnailRequest);
      return coordinator;
    } else {
      // 没有缩略图时,构造请求
      return obtainRequest(
          target,
          targetListener,
          requestOptions,
          parentCoordinator,
          transitionOptions,
          priority,
          overrideWidth,
          overrideHeight,
          callbackExecutor);
    }
  }

  private Request obtainRequest(
      Target target,
      RequestListener targetListener,
      BaseRequestOptions requestOptions,
      RequestCoordinator requestCoordinator,
      TransitionOptions transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      Executor callbackExecutor) {
    return SingleRequest.obtain(
        context,
        glideContext,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        glideContext.getEngine(),
        transitionOptions.getTransitionFactory(),
        callbackExecutor);
  }
}

构建目标Request请求的代码比较长,如果我们配置了缩略图要求,它将构建缩略图请求,并和目标请求一起放入到协调器中。ThumbnailRequestCoordinator 请求协调器,可以用来协调各请求的顺序。

我们只分析目标请求流程,也就是没有设置缩略图的情况。由obtain静态方法可以看到,最终获得的目标Request对象就是SingleRequest,它封装了图片请求需要的各个成员。

public final class SingleRequest implements Request,
    SizeReadyCallback,
    ResourceCallback,
    FactoryPools.Poolable {
    
    public static  SingleRequest obtain(
      Context context,
      GlideContext glideContext,
      Object model,
      Class transcodeClass,
      BaseRequestOptions requestOptions,
      int overrideWidth,
      int overrideHeight,
      Priority priority,
      Target target,
      RequestListener targetListener,
      @Nullable List> requestListeners,
      RequestCoordinator requestCoordinator,
      Engine engine,
      TransitionFactory animationFactory,
      Executor callbackExecutor) {
    @SuppressWarnings("unchecked") SingleRequest request =
        (SingleRequest) POOL.acquire();

    //创建SingleRequest对象
    if (request == null) {
      request = new SingleRequest<>();
    }
    //初始化
    request.init(
        context,
        glideContext,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        engine,
        animationFactory,
        callbackExecutor);
    return request;
  }

  //赋值成员变量
  private synchronized void init(
      Context context,
      GlideContext glideContext,
      Object model,
      Class transcodeClass,
      BaseRequestOptions requestOptions,
      int overrideWidth,
      int overrideHeight,
      Priority priority,
      Target target,
      RequestListener targetListener,
      @Nullable List> requestListeners,
      RequestCoordinator requestCoordinator,
      Engine engine,
      TransitionFactory animationFactory,
      Executor callbackExecutor) {
    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.requestListeners = requestListeners;
    this.requestCoordinator = requestCoordinator;
    this.engine = engine;
    this.animationFactory = animationFactory;
    this.callbackExecutor = callbackExecutor;
    status = Status.PENDING;

    if (requestOrigin == null && glideContext.isLoggingRequestOriginsEnabled()) {
      requestOrigin = new RuntimeException("Glide request origin trace");
    }
  }

}

目标Request已经构建完成,再回到requestManager.track(target, request)这行代码,看Request如何被发出去的。它通过RequestManager来调用。

public class RequestManager implements LifecycleListener,
    ModelTypes> {
  
    //请求追踪器
  private final RequestTracker requestTracker;

  public RequestManager(
      @NonNull Glide glide, @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
    this(
        glide,
        lifecycle,
        treeNode,
        new RequestTracker(),//创建请求追踪器
        glide.getConnectivityMonitorFactory(),
        context);
  }

  synchronized void track(@NonNull Target target, @NonNull Request request) {
    targetTracker.track(target);
    // 开始请求
    requestTracker.runRequest(request);
  }


}

任务被移交给了RequestTracker请求追踪器进行追踪,这个对象RequestManager在构造时创建的。

public class RequestTracker {
   private final Set requests =
      Collections.newSetFromMap(new WeakHashMap());
  private final List pendingRequests = new ArrayList<>();
  private boolean isPaused;

  //执行请求任务
  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);
    }

  }

如果任务此时被暂停了,那么将清理掉某些资源,但这个Request 还可以通过begin()方法来重新发出,所以被保存到pendingRequests待处理
列表中。

上面说过,所有图片请求相关的成员都被封装到Request(SingleRequest )对象中,它将指定Target去加载自己的资源。

public final class SingleRequest implements Request,
    SizeReadyCallback,
    ResourceCallback,
    FactoryPools.Poolable {

  public synchronized void begin() {
    assertNotCallingCallbacks();
    stateVerifier.throwIfRecycled();
    startTime = LogTime.getLogTime();
    //即地址为null
    if (model == null) {
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        width = overrideWidth;
        height = overrideHeight;
      }
   
      int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
      //加载出错处理
      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;
    }

    status = Status.WAITING_FOR_SIZE;
  // 如果指定了宽高,直接回调 onSizeReady
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
    } else {
    // 根据 target 的宽高来加载图片的宽高
      target.getSize(this);
    }

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

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

    //加载图片并返回状态
    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);
    
    if (status != Status.RUNNING) {
      loadStatus = null;
    }
    if (IS_VERBOSE_LOGGABLE) {
      logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
    }
  }

}

加载分两种情况,如果指定了一个固定的宽高,就会直接执行onSizeReady()方法。如果没指定的话,调用target.getSize()方法。这个target.getSize()方法,它会根据ImageView布局设置的宽高,算出图片应该显示的宽高。计算完之后,它也会调用onSizeReady()方法。

但请求加载流程还不是在这个类中执行的,它把这个任务交给了Engine对象来处理,这个对象是在GlideBuilder的build方法中创建的,我们前面分析过,在build方法中还创建了几个缓存池和以及复用池,这些池子都封装到了Engine对象中。并且在随后的Glide构造方法中构建GlideContext对象时,将其保存到这个上下文中。

public class Engine implements EngineJobListener,
    MemoryCache.ResourceRemovedListener,
    EngineResource.ResourceListener {




    public synchronized  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) {


    long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;

    // 创建资源索引 KEY
    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 (VERBOSE_IS_LOGGABLE) {
        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 (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from cache", startTime, key);
      }
      return null;
    }
    // 获取已经存在的加载任务 ,onlyRetrieveFromCache 参数表示是否只加载缓存中的数据
    EngineJob current = jobs.get(key, onlyRetrieveFromCache);
    if (current != null) {
      // 添加 SingleRequest 回调对象 
      current.addCallback(cb, callbackExecutor);
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Added to existing load", startTime, key);
      }
      return new LoadStatus(cb, current);
    }

    // 构造 EngineJob 对象,用于启动解码任务
    EngineJob engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);

    //构建解码器并初始化
    DecodeJob decodeJob =
        decodeJobFactory.build(
            glideContext,
            model,
            key,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            onlyRetrieveFromCache,
            options,
            engineJob);
    // 缓存加载任务
    jobs.put(key, engineJob);
    // 添加 SingleRequest 回调对象 
    engineJob.addCallback(cb, callbackExecutor);
    // 执行解码任务
    engineJob.start(decodeJob);

    if (VERBOSE_IS_LOGGABLE) {
      logWithTimeAndKey("Started new load", startTime, key);
    }
    return new LoadStatus(cb, engineJob);
  }

}

既然Engine 封装了许多缓存池,那么做网络请求前,必然先看缓存有没有。buildKey方法将几个参数封装成EngineKey ,根据这个Key 来获取内存缓存数据,如果存在,则直接回调成功,如果不存在,则新建EngineJob 对象和DecodeJob解码器,DecodeJob实现了Runnable,通过EngineJob 对象调用start来启动。

缓存的获取这里先不分析,我们分析首次加载,即没有缓存的情况。那么,紧接着的工作又传递给了EngineJob 对象,它会通过线程池来开启DecodeJob这个Runnable。

class EngineJob implements DecodeJob.Callback,
    Poolable {

    //通过线程池启动图片加载任务
  public synchronized void start(DecodeJob decodeJob) {
    this.decodeJob = decodeJob;
    GlideExecutor executor = decodeJob.willDecodeFromCache()
        ? diskCacheExecutor
        : getActiveSourceExecutor();
    executor.execute(decodeJob);
  }

}

很显然,GlideExecutor 是Glide自定义的Executor,它内部实现了线程池。因此,我们直接看DecodeJob的run方法。

class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable>,
    Poolable {
  //加载辅助类
  private final DecodeHelper decodeHelper = new DecodeHelper<>();


    DecodeJob init(
      GlideContext glideContext,
      Object model,
      EngineKey loadKey,
      Key signature,
      int width,
      int height,
      Class resourceClass,
      Class transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map, Transformation> transformations,
      boolean isTransformationRequired,
      boolean isScaleOnlyOrNoTransform,
      boolean onlyRetrieveFromCache,
      Options options,
      Callback callback,
      int order) {
    decodeHelper.init(
        glideContext,
        model,
        signature,
        width,
        height,
        diskCacheStrategy,
        resourceClass,
        transcodeClass,
        priority,
        options,
        transformations,
        isTransformationRequired,
        isScaleOnlyOrNoTransform,
        diskCacheProvider);
    this.glideContext = glideContext;
    this.signature = signature;
    this.priority = priority;
    this.loadKey = loadKey;
    this.width = width;
    this.height = height;
    this.diskCacheStrategy = diskCacheStrategy;
    this.onlyRetrieveFromCache = onlyRetrieveFromCache;
    this.options = options;
    this.callback = callback;
    this.order = order;
    this.runReason = RunReason.INITIALIZE;//初始化RunReason为INITIALIZE
    this.model = model;
    return this;
  }

   public void run() {
   
    GlideTrace.beginSectionFormat("DecodeJob#run(model=%s)", model);
  
    DataFetcher localFetcher = currentFetcher;
    try {
      if (isCancelled) {
        notifyFailed();
        return;
      }
      //进入runWrapped
      runWrapped();
    } catch (CallbackException e) {
       throw e;
    } catch (Throwable t) {
 
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "DecodeJob threw unexpectedly"
            + ", isCancelled: " + isCancelled
            + ", stage: " + stage, t);
      }

      if (stage != Stage.ENCODE) {
        throwables.add(t);
        notifyFailed();
      }
      if (!isCancelled) {
        throw t;
      }
      throw t;
    } finally {
      if (localFetcher != null) {
        localFetcher.cleanup();
      }
      GlideTrace.endSection();
    }
  }

   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 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;
    while (!isCancelled && currentGenerator != null
        && !(isStarted = currentGenerator.startNext())) {
      stage = getNextStage(stage);
      currentGenerator = getNextGenerator();

      if (stage == Stage.SOURCE) {
        reschedule();
        return;
      }
    }
   
    if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
      notifyFailed();
    }

  }
}

在DecodeJob被构造和初始化时,RunReason设置为INITIALIZE,也就是说,runWrapped进入了INITIALIZE这个case,如代码所示,有处理过的缓存资源加载器、原始图片资源缓存加载器和远程图片资源加载器3种不同类型的加载器,会根据当前的状态决定使用哪一个,由于是首次加载,因此,将获取到远程图片资源加载器,即SourceGenerator这个对象。

runGenerators方法内是一个while递归循环,它通过加载器的startNext方法来执行加载的任务,开启成功结束循环,不再寻找新的加载器。

class SourceGenerator implements DataFetcherGenerator,
    DataFetcher.DataCallback,
    DataFetcherGenerator.FetcherReadyCallback {

  private final DecodeHelper helper;

  private volatile ModelLoader.LoadData loadData;

  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;
     // 遍历所有的ModelLoader模块加载器
    while (!started && hasNextModelLoader()) {
      //拿到 HttpGlideUrlLoader 对象
      loadData = helper.getLoadData().get(loadDataListIndex++);
      if (loadData != null
          && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
          || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
        started = true;
        // 调用 HttpUrlFetcher 的 loadData 方法
        loadData.fetcher.loadData(helper.getPriority(), this);
      }
    }
    return started;
  }

}
 
 

DecodeHelper是在Engine中构建的,使用getLoadData获取到ModelLoader的列表。

final class DecodeHelper {

    //获取List>
   List> getLoadData() {
    if (!isLoadDataSet) {
      isLoadDataSet = true;
      loadData.clear();
      List> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
      
      for (int i = 0, size = modelLoaders.size(); i < size; i++) {
        //这个ModelLoader为HttpGlideUrlLoader
        ModelLoader modelLoader = modelLoaders.get(i);
        //构建LoadData
        LoadData current =
            modelLoader.buildLoadData(model, width, height, options);
        if (current != null) {
          loadData.add(current);
        }
      }
    }
    return loadData;
  }
}

这里获取到ModelLoader为HttpGlideUrlLoader类型的,通过buildLoadData构建一个ModelLoader.LoadData对象。

public class HttpGlideUrlLoader implements ModelLoader {


   public LoadData buildLoadData(@NonNull GlideUrl model, int width, int height,
      @NonNull Options options) {
     GlideUrl url = model;
    if (modelCache != null) {
      url = modelCache.get(model, 0, 0);
      if (url == null) {
        modelCache.put(model, 0, 0, model);
        url = model;
      }
    }
    int timeout = options.get(TIMEOUT);
    //构建HttpUrlFetcher将它传递给LoadData
    return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
   }
}

因此,上面loadData.fetcher.loadData代码就是在HttpUrlFetcher中执行的。

public class HttpUrlFetcher implements DataFetcher {
    
  @Override
  public void loadData(@NonNull Priority priority,
      @NonNull DataCallback callback) {
    long startTime = LogTime.getLogTime();

    // 调用 loadDataWithRedirects 方法执行网络请求
    try {
      InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
      //将输入流回调给DataCallback
      callback.onDataReady(result);
    } catch (IOException e) {
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "Failed to load data for url", e);
      }
      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 headers) throws IOException {

    if (redirects >= MAXIMUM_REDIRECTS) {
      throw new HttpException("Too many (> " + MAXIMUM_REDIRECTS + ") redirects!");
    } else {
     try {
        if (lastUrl != null && url.toURI().equals(lastUrl.toURI())) {
          throw new HttpException("In re-direct loop");
        }
      } catch (URISyntaxException e) {
        
      }
    }
    //根据url构建Connection 
    urlConnection = connectionFactory.build(url);
    for (Map.Entry headerEntry : headers.entrySet()) {
      urlConnection.addRequestProperty(headerEntry.getKey(), headerEntry.getValue());
    }
    urlConnection.setConnectTimeout(timeout);
    urlConnection.setReadTimeout(timeout);
    urlConnection.setUseCaches(false);
    urlConnection.setDoInput(true);

    urlConnection.setInstanceFollowRedirects(false);

    //请求下载
    urlConnection.connect();
   
    //先将输入流保存
    stream = urlConnection.getInputStream();
    //如果没有突然被取消
    if (isCancelled) {
      return null;
    }
    //状态码
    final int statusCode = urlConnection.getResponseCode();
    //状态码为200,将输入流返回
    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);
      
      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);
    }
  }

  //获取输入流
   private InputStream getStreamForSuccessfulRequest(HttpURLConnection urlConnection)
      throws IOException {
    if (TextUtils.isEmpty(urlConnection.getContentEncoding())) {
      int contentLength = urlConnection.getContentLength();
      stream = ContentLengthInputStream.obtain(urlConnection.getInputStream(), contentLength);
    } else {
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "Got non empty content encoding: " + urlConnection.getContentEncoding());
      }
      stream = urlConnection.getInputStream();
    }
    return stream;
  }

  //状态码为200
  private static boolean isHttpOk(int statusCode) {
    return statusCode / 100 == 2;
  }
}

分析到这,总算看到网络请求的调用了。如果状态为200,那么将获取得数据输入流,回调给DataCallback接口,它是从loadData方法传递进来的,再回头loadData的调用知道,它其实就是SourceGenerator对象。


class SourceGenerator implements DataFetcherGenerator,
    DataFetcher.DataCallback,
    DataFetcherGenerator.FetcherReadyCallback {

   private final FetcherReadyCallback cb;
   private final DecodeHelper helper;
    //缓存流
    private Object dataToCache;
  SourceGenerator(DecodeHelper helper, FetcherReadyCallback cb) {
    this.helper = helper;
    this.cb = cb;
  }

    @Override
  public void onDataReady(Object data) {
    DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
    //如果设置了磁盘缓存
    if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
      //将数据流缓存到磁盘对象中
      dataToCache = data;
      // 重启 DecodeJob 任务
       cb.reschedule();
    } else {
      //没有缓存,回调给DecodeJob
      cb.onDataFetcherReady(loadData.sourceKey, data, loadData.fetcher,
          loadData.fetcher.getDataSource(), originalKey);
    }
  }

}
 
 

Glide认为远程网络图片获取是昂贵的,所以默认情况下网络图片会缓存原图,但本地图片,包括drawable/assets等不会缓存原图。

有没有缓存,最终都会调用到onDataFetcherReady这个方法。与没有缓存相比,有缓存流程上的区别是,会将数据流缓存到磁盘中,然后开一个新的线程,再通过另一个缓存加载器处理,并获取数据流。以上说过,默认是有缓存原图的,因此,我们先分析缓存的调用流程。

在这里提一下,整个流程的调用就类似一个命令下发,这个命令会一层层往下传递,传给到最后一棒的对象去取得数据,再沿着原来的路线,将完成的数据,一层层往回传。这一点务必记住,后面的流程都是在一边处理数据,一边向之前的对象传递,直至传给SingleRequest这个对象里的Target成员,来显示图片。

因此,这里就开始了往前的传递,调用reschedule的对象为DecodeJob。

class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable>,
    Poolable {

 @Override
  public void reschedule() {
    //RunReason被置为SWITCH_TO_SOURCE_SERVICE
    runReason = RunReason.SWITCH_TO_SOURCE_SERVICE;
    //回调给EngineJob
    callback.reschedule(this);
  }

RunReason被置为SWITCH_TO_SOURCE_SERVICE。紧接着再次往回通知EngineJob对象。

class EngineJob implements DecodeJob.Callback,
    Poolable {

  @Override
  public void reschedule(DecodeJob job) {
        getActiveSourceExecutor().execute(job);
  }
}

重新开启线程,执行DecodeJob这个任务。这回直接执行runGenerators方法,再次调用SourceGenerator的startNext方法,此时缓存就不为null了。

class SourceGenerator implements DataFetcherGenerator,
    DataFetcher.DataCallback,
    DataFetcherGenerator.FetcherReadyCallback {
  //缓存流
  private Object dataToCache;
  //缓存加载器
  private DataCacheGenerator sourceCacheGenerator;

  @Override
  public boolean startNext() {
    //缓存不为null
    if (dataToCache != null) {
      Object data = dataToCache;
      dataToCache = null;
      cacheData(data);
    }
  //此时sourceCacheGenerator 不为null
  if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
      return true;
    }
   ......
  }

  private void cacheData(Object dataToCache) {
    long startTime = LogTime.getLogTime();
    try {
      Encoder encoder = helper.getSourceEncoder(dataToCache);
      DataCacheWriter writer =
          new DataCacheWriter<>(encoder, dataToCache, helper.getOptions());
      originalKey = new DataCacheKey(loadData.sourceKey, helper.getSignature());
      helper.getDiskCache().put(originalKey, writer);
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Finished encoding source to cache"
            + ", key: " + originalKey
            + ", data: " + dataToCache
            + ", encoder: " + encoder
            + ", duration: " + LogTime.getElapsedMillis(startTime));
      }
    } finally {
      loadData.fetcher.cleanup();
    }

    //构建缓存加载器来处理
    sourceCacheGenerator =
        new DataCacheGenerator(Collections.singletonList(loadData.sourceKey), helper, this);
  }
 
 

dataToCache 将不再是 null ,所以会将数据缓存到本地硬盘,并启动另一个加载器DataCacheGenerator,这个加载器正是用来加载缓存在本地的图片的。它赋值给了成员变量sourceCacheGenerator ,随后执行其startNext方法。

DataCacheGenerator和ResourceCacheGenerator这两个加载器跟SourceGenerator类似,只不过根据不同情形的图片进行加载:

  • DataCacheGenerator:用于加载原始图片。
  • ResourceCacheGenerator:用于加载处理过的图片。
  • SourceGenerator:用于加载网络图片。

因此,数据从缓存中加载成功,同样回传给DataCacheGenerator的 onDataReady方法。

class DataCacheGenerator implements DataFetcherGenerator,
    DataFetcher.DataCallback {

   public void onDataReady(Object data) {
    cb.onDataFetcherReady(sourceKey, data, loadData.fetcher, DataSource.DATA_DISK_CACHE, sourceKey);
  }
}
 
 

前面我们提到过,有没有缓存,最终都会调用DecodeJob的onDataFetcherReady方法,因为它是用来解码的。

class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable>,
    Poolable {

   @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 {
      GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
      try {
        //解码数据
        decodeFromRetrievedData();
      } finally {
        GlideTrace.endSection();
      }
    }

  //解码获取Resource
   private void decodeFromRetrievedData() {
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey("Retrieved data", startFetchTime,
          "data: " + currentData
              + ", cache key: " + currentSourceKey
              + ", fetcher: " + currentFetcher);
    }
    Resource resource = null;
    try {
      //解码得到LazyBitmapDrawableResource
      resource = decodeFromData(currentFetcher, currentData, currentDataSource);
    } catch (GlideException e) {
      e.setLoggingDetails(currentAttemptingKey, currentDataSource);
      throwables.add(e);
    }

    //进行编码输出
    if (resource != null) {
      notifyEncodeAndRelease(resource, currentDataSource);
    } else {
      runGenerators();
    }
  }

  private  Resource decodeFromData(DataFetcher fetcher, Data data,
      DataSource dataSource) throws GlideException {
    try {
      if (data == null) {
        return null;
      }
      long startTime = LogTime.getLogTime();
      //从DecodeHelper中获取LoadPath对象
      Resource result = decodeFromFetcher(data, dataSource);
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logWithTimeAndKey("Decoded result " + result, startTime);
      }
      return result;
    } finally {
      fetcher.cleanup();
    }
  }

  private  Resource decodeFromFetcher(Data data, DataSource dataSource)
      throws GlideException {
    LoadPath path = decodeHelper.getLoadPath((Class) data.getClass());
    return runLoadPath(data, dataSource, path);
  }

  private  Resource runLoadPath(Data data, DataSource dataSource,
      LoadPath path) throws GlideException {
    Options options = getOptionsWithHardwareConfig(dataSource);
    DataRewinder rewinder = glideContext.getRegistry().getRewinder(data);
    try {
      //使用LoadPath进行解码
      return path.load(
          rewinder, options, width, height, new DecodeCallback(dataSource));
    } finally {
      rewinder.cleanup();
    }
  }
}

解码的流程最终是通过LoadPath这个对象来进行处理的。它是根据传入的处理数据,来返回特定的数据解码处理器对象。

public class LoadPath {
  

  public Resource load(DataRewinder rewinder, @NonNull Options options, int width,
      int height, DecodePath.DecodeCallback decodeCallback) throws GlideException {
    List throwables = Preconditions.checkNotNull(listPool.acquire());
    try {
      return loadWithExceptionList(rewinder, options, width, height, decodeCallback, throwables);
    } finally {
      listPool.release(throwables);
    }
  }

 private Resource loadWithExceptionList(DataRewinder rewinder,
      @NonNull Options options,
      int width, int height, DecodePath.DecodeCallback decodeCallback,
      List exceptions) throws GlideException {

    Resource result = null;
    //遍历从列表获取DecodePath进行解码
    for (int i = 0, size = decodePaths.size(); i < size; i++) {
      DecodePath path = decodePaths.get(i);
      try {
        //开始解码
        result = path.decode(rewinder, width, height, options, decodeCallback);
      } catch (GlideException e) {
        exceptions.add(e);
      }
      if (result != null) {
        break;
      }
    }

    if (result == null) {
      throw new GlideException(failureMessage, new ArrayList<>(exceptions));
    }

    return result;
  }
}

DecodePath类还并不是最终的解码器,它只是封装解码和转码的工具,它本身不做解码转码的具体操作。

public class DecodePath {
  //转码器
  private final ResourceTranscoder transcoder;

  public Resource decode(DataRewinder rewinder, int width, int height,
      @NonNull Options options, DecodeCallback callback) throws GlideException {
     // 返回的可能是 BitmapResource 对象,看具体类型
    Resource decoded = decodeResource(rewinder, width, height, options);

    // 回调 DecodeJob 的 onResourceDecoded 方法,返回需要转码的类型
    Resource transformed = callback.onResourceDecoded(decoded);

    //转码 BitmapResource,返回 LazyBitmapDrawableResource
    return transcoder.transcode(transformed, options);
  }

  private Resource decodeResourceWithList(DataRewinder rewinder, int width,
      int height, @NonNull Options options, List exceptions) throws GlideException {

    Resource result = null;

   //遍历获取StreamBitmapDecoder
    for (int i = 0, size = decoders.size(); i < size; i++) {
      ResourceDecoder decoder = decoders.get(i);
      try {
        DataType data = rewinder.rewindAndGet();
        if (decoder.handles(data, options)) {
          data = rewinder.rewindAndGet();
          //解码成Drawable 
          result = decoder.decode(data, width, height, options);
        }
       
      } catch (IOException | RuntimeException | OutOfMemoryError e) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
          Log.v(TAG, "Failed to decode data for " + decoder, e);
        }
        exceptions.add(e);
      }

      if (result != null) {
        break;
      }
    }

    if (result == null) {
      throw new GlideException(failureMessage, new ArrayList<>(exceptions));
    }
    return result;
  }

}

这里需要的是 Drawable 类型,所以,decodeResource方法最终会通过 StreamBitmapDecoder将数据流解码成一个 BitmapResource 对象。再通过ResourceTranscoder转码器,它是BitmapDrawableTranscoder类型的,转码为LazyBitmapDrawableResource对象。

public class BitmapDrawableTranscoder implements ResourceTranscoder {
  private final Resources resources;

  @SuppressWarnings("unused")
  public BitmapDrawableTranscoder(@NonNull Context context) {
    this(context.getResources());
  }
 
  @Deprecated
  public BitmapDrawableTranscoder(
      @NonNull Resources resources, @SuppressWarnings("unused") BitmapPool bitmapPool) {
    this(resources);
  }

  public BitmapDrawableTranscoder(@NonNull Resources resources) {
    this.resources = Preconditions.checkNotNull(resources);
  }

  //转码
  @Override
  public Resource transcode(@NonNull Resource toTranscode,
      @NonNull Options options) {
    return LazyBitmapDrawableResource.obtain(resources, toTranscode);
  }
}
public final class LazyBitmapDrawableResource implements Resource,
    Initializable {

  //获取LazyBitmapDrawableResource对象
  public static Resource obtain(
      @NonNull Resources resources, @Nullable Resource bitmapResource) {
    if (bitmapResource == null) {
      return null;
    }
    return new LazyBitmapDrawableResource(resources, bitmapResource);

  }

  //获取BitmapDrawable
  @Override
  public BitmapDrawable get() {
    return new BitmapDrawable(resources, bitmapResource.get());
  }

}

这里注意到get方法返回了BitmapDrawable对象,它就是最终用来显示到ImageView上的类型。现在解码和转码工作已经完成了。所以,数据继续往回传递通知上层,将获取到的结果进行展示。

因此,回到DecodeJob类的decodeFromRetrievedData方法内部,调用notifyEncodeAndRelease 继续往下执行。

class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable>,
    Poolable {

  private void notifyEncodeAndRelease(Resource resource, DataSource dataSource) {
    if (resource instanceof Initializable) {
      ((Initializable) resource).initialize();
    }
    //将资源锁定
    Resource result = resource;
    LockedResource 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();
      }
    }
 
    onEncodeComplete();
  }

  private void notifyComplete(Resource resource, DataSource dataSource) {
    setNotifiedOrThrow();
    //回调给EngineJob
    callback.onResourceReady(resource, dataSource);
  }

}

LazyBitmapDrawableResource数据继续往回传给EngineJob类。它还会继续往上传给SingleRequest类。

class EngineJob implements DecodeJob.Callback,
    Poolable {
//这是LazyBitmapDrawableResource
 private Resource resource;

  @Override
  public void onResourceReady(Resource resource, DataSource dataSource) {
    //保存数据
    synchronized (this) {
      this.resource = resource;
      this.dataSource = dataSource;
    }
    notifyCallbacksOfResult();
  }

  @Synthetic
  void notifyCallbacksOfResult() {

    ResourceCallbacksAndExecutors copy;
    Key localKey;
    EngineResource localResource;
    synchronized (this) {
      stateVerifier.throwIfRecycled();
      if (isCancelled) {
        resource.recycle();
        release();
        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
      engineResource = engineResourceFactory.build(resource, isCacheable);
      
      hasResource = true;
      copy = cbs.copy();
      incrementPendingCallbacks(copy.size() + 1);
      localKey = key;
      localResource = engineResource;
    }

    listener.onEngineJobComplete(this, localKey, localResource);
    //通过子线程回调
    for (final ResourceCallbackAndExecutor entry : copy) {
      entry.executor.execute(new CallResourceReady(entry.cb));
    }
    decrementPendingCallbacks();
  }


   private class CallResourceReady implements Runnable {

    private final ResourceCallback cb;

    CallResourceReady(ResourceCallback cb) {
      this.cb = cb;
    }

    @Override
    public void run() {
      synchronized (EngineJob.this) {
        if (cbs.contains(cb)) {
       
          engineResource.acquire();
          //调用callCallbackOnResourceReady传递给SingleRequest
          callCallbackOnResourceReady(cb);
          removeCallback(cb);
        }
        decrementPendingCallbacks();
      }
    }
  }

  @SuppressWarnings("WeakerAccess")
  @Synthetic
  synchronized void callCallbackOnResourceReady(ResourceCallback cb) {
    try {
      //调用SingleRequest的onResourceReady方法
      cb.onResourceReady(engineResource, dataSource);
    } catch (Throwable t) {
      throw new CallbackException(t);
    }
  }

}

EngineJob构建了一个EngineResource,将LazyBitmapDrawableResource封装在它的内部,然后开启线程,将数据传递给了SingleRequest类。

public final class SingleRequest implements Request,
    SizeReadyCallback,
    ResourceCallback,
    FactoryPools.Poolable {
  
     @Override
  public synchronized void onResourceReady(Resource resource, DataSource dataSource) {
    stateVerifier.throwIfRecycled();
    loadStatus = null;
    if (resource == null) {
      GlideException exception = new GlideException("Expected to receive a Resource with an "
          + "object of " + transcodeClass + " inside, but instead got null.");
      onLoadFailed(exception);
      return;
    }
    从EngineResource中获取BitmapDrawable对象
    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);
      status = Status.COMPLETE;
      return;
    }
  //通知Target显示图片
    onResourceReady((Resource) resource, (R) received, dataSource);
  }

private synchronized void onResourceReady(Resource resource, R result, DataSource dataSource) {
    
    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 {
      boolean anyListenerHandledUpdatingTarget = false;
      if (requestListeners != null) {
        for (RequestListener listener : requestListeners) {
          anyListenerHandledUpdatingTarget |=
              listener.onResourceReady(result, model, target, dataSource, isFirstResource);
        }
      }
      anyListenerHandledUpdatingTarget |=
          targetListener != null
              && targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);

      if (!anyListenerHandledUpdatingTarget) {
        Transition animation =
            animationFactory.build(dataSource, isFirstResource);
        //显示资源
        target.onResourceReady(result, animation);
      }
    } finally {
      isCallingCallbacks = false;
    }

    notifyLoadSuccess();
  }
}

注意代码中的resource.get()调用,这个resource是传递过来的EngineResource,上面说过,它已经持有了LazyBitmapDrawableResource,这个get方法,便会调用LazyBitmapDrawableResource的get方法获取到BitmapDrawable对象,紧接着调用onResourceReady方法让Target去展示图片。

在最前面分析说过,这个Target是ImageViewTarget的子类,BitmapImageViewTarget。

public abstract class ImageViewTarget extends ViewTarget
    implements Transition.ViewAdapter {
  
   @Override
  public void onResourceReady(@NonNull Z resource, @Nullable Transition transition) {
    if (transition == null || !transition.transition(resource, this)) {
      //设置资源
      setResourceInternal(resource);
    } else {
      maybeUpdateAnimatable(resource);
    }
  }

    private void setResourceInternal(@Nullable Z resource) {
    //调用子类方法
    setResource(resource);
    maybeUpdateAnimatable(resource);
  }
  
   protected abstract void setResource(@Nullable Z resource);
}
public class DrawableImageViewTarget extends ImageViewTarget {

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

  @SuppressWarnings({"unused", "deprecation"})
  @Deprecated
  public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }

  //显示图片
  @Override
  protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);
  }
}

到此,Glide整个图片加载流程分析完毕。其中的into流程是最复杂的,因为Glide做了大量的缓存处理和对象复用。但整个基本调用流程是:下发一个Request后,通过网络请求获得数据,进行解码和转码,再沿路返回到Request类中,让Target去做图片展示。

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