Glide源码解析

40 阅读13分钟

1. Glide的使用

  • 导包
implementation 'com.github.bumptech.glide:glide:4.15.1'
  • 具体使用
Glide.with(this).load(url).into(imageView)

2.源码阅读

2.1 Glide.with(...)相关源码

  • 包含多个重载方法
// Glide.java
@NonNull
public static RequestManager with(@NonNull Context context) {
  return getRetriever(context).get(context);
}

@NonNull
@Deprecated
public static RequestManager with(@NonNull Activity activity) {
  return getRetriever(activity).get(activity);
}

@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
  return getRetriever(activity).get(activity);
}

@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
  return getRetriever(fragment.getContext()).get(fragment);
}

@SuppressWarnings("deprecation")
@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment) {
  return getRetriever(fragment.getActivity()).get(fragment);
}

@NonNull
public static RequestManager with(@NonNull View view) {
  return getRetriever(view.getContext()).get(view);
}
  • 最终调用的均为
// Glide.java
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  ...
  return Glide.get(context).getRequestManagerRetriever();
}
  • Glide.get(context)实现Glide相关的初始化
// Glide.java
/** DCL实例化Glide */
public static Glide get(@NonNull Context context) {
  if (glide == null) {
    GeneratedAppGlideModule annotationGeneratedModule =
        getAnnotationGeneratedGlideModules(context.getApplicationContext());
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context, annotationGeneratedModule);
      }
    }
  }

  return glide;
}

@GuardedBy("Glide.class")
@VisibleForTesting
static void checkAndInitializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  ...
    initializeGlide(context, generatedAppGlideModule);
  ...
}

@GuardedBy("Glide.class")
private static void initializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}

@GuardedBy("Glide.class")
@SuppressWarnings("deprecation")
private static void initializeGlide(
    @NonNull Context context,
    @NonNull GlideBuilder builder,
    @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
  Context applicationContext = context.getApplicationContext();
  List<GlideModule> manifestModules = Collections.emptyList();
  if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
    manifestModules = new ManifestParser(applicationContext).parse();
  }

  if (annotationGeneratedModule != null
      && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
    Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
    Iterator<GlideModule> iterator = manifestModules.iterator();
    while (iterator.hasNext()) {
      GlideModule current = iterator.next();
      if (!excludedModuleClasses.contains(current.getClass())) {
        continue;
      }
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
      }
      iterator.remove();
    }
  }

  if (Log.isLoggable(TAG, Log.DEBUG)) {
    for (GlideModule glideModule : manifestModules) {
      Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
    }
  }

  RequestManagerRetriever.RequestManagerFactory factory =
      annotationGeneratedModule != null
          ? annotationGeneratedModule.getRequestManagerFactory()
          : null;
  builder.setRequestManagerFactory(factory);
  for (GlideModule module : manifestModules) {
    module.applyOptions(applicationContext, builder);
  }
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.applyOptions(applicationContext, builder);
  }
  // 使用Builder模式构建Glide对象
  Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
  applicationContext.registerComponentCallbacks(glide);
  Glide.glide = glide;
}
// GlideBuilder.java
@NonNull
Glide build(
    @NonNull Context context,
    List<GlideModule> manifestModules,
    AppGlideModule annotationGeneratedGlideModule) {
  // 创建请求图片线程池sourceExecutor
  if (sourceExecutor == null) {
    sourceExecutor = GlideExecutor.newSourceExecutor();
  }

  // 创建硬盘缓存线程池diskCacheExecutor
  if (diskCacheExecutor == null) {
    diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
  }

  // 创建动画线程池animationExecutor
  if (animationExecutor == null) {
    animationExecutor = GlideExecutor.newAnimationExecutor();
  }

  if (memorySizeCalculator == null) {
    memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
  }

  if (connectivityMonitorFactory == null) {
    connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
  }

  if (bitmapPool == null) {
    // 依据设备的屏幕密度和尺寸生成建议位图池大小
    int size = memorySizeCalculator.getBitmapPoolSize();
    if (size > 0) {
      bitmapPool = new LruBitmapPool(size);
    } else {
      bitmapPool = new BitmapPoolAdapter();
    }
  }

  // 创建对象数组缓存池LruArrayPool,默认4M
  if (arrayPool == null) {
    arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
  }

  // 创建LruResourceCache,内存缓存
  if (memoryCache == null) {
    memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
  }

  if (diskCacheFactory == null) {
    diskCacheFactory = new InternalCacheDiskCacheFactory(context);
  }

  // 创建任务和资源管理引擎(线程池,内存缓存和硬盘缓存对象)
  if (engine == null) {
    engine =
        new Engine(
            memoryCache,
            diskCacheFactory,
            diskCacheExecutor,
            sourceExecutor,
            GlideExecutor.newUnlimitedSourceExecutor(),
            animationExecutor,
            isActiveResourceRetentionAllowed);
  }

  if (defaultRequestListeners == null) {
    defaultRequestListeners = Collections.emptyList();
  } else {
    defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
  }

  GlideExperiments experiments = glideExperimentsBuilder.build();
  RequestManagerRetriever requestManagerRetriever =
      new RequestManagerRetriever(requestManagerFactory, experiments);

  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptionsFactory,
      defaultTransitionOptions,
      defaultRequestListeners,
      manifestModules,
      annotationGeneratedGlideModule,
      experiments);
}
  • 主要完成了一系列的初始化,包含各式各样的配置信息(包括缓存,请求线程池,大小,图片格式等等)以及glide对象
  • 最后是调用了requestManagerRetriever.get(...)
// Glide.java
@NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
  return requestManagerRetriever;
}
// RequestManagerRetriever.java
@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)) {
    // 如果当前线程是主线程且context不是Application走相应的get重载方法
    if (context instanceof FragmentActivity) {
      return get((FragmentActivity) context);
    } else if (context instanceof Activity) {
      return get((Activity) context);
    } else if (context instanceof ContextWrapper
        && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
      return get(((ContextWrapper) context).getBaseContext());
    }
  }

  // 否则直接将请求与ApplicationLifecycle关联
  return getApplicationManager(context);
}

@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
  if (Util.isOnBackgroundThread()) {
    return get(activity.getApplicationContext());
  }
  assertNotDestroyed(activity);
  frameWaiter.registerSelf(activity);
  boolean isActivityVisible = isActivityVisible(activity);
  Glide glide = Glide.get(activity.getApplicationContext());
  return lifecycleRequestManagerRetriever.getOrCreate(
      activity,
      glide,
      activity.getLifecycle(),
      activity.getSupportFragmentManager(),
      isActivityVisible);
}

@NonNull
public RequestManager get(@NonNull Fragment fragment) {
  Preconditions.checkNotNull(
      fragment.getContext(),
      "You cannot start a load on a fragment before it is attached or after it is destroyed");
  if (Util.isOnBackgroundThread()) {
    return get(fragment.getContext().getApplicationContext());
  }
  if (fragment.getActivity() != null) {
    frameWaiter.registerSelf(fragment.getActivity());
  }
  FragmentManager fm = fragment.getChildFragmentManager();
  Context context = fragment.getContext();
  Glide glide = Glide.get(context.getApplicationContext());
  return lifecycleRequestManagerRetriever.getOrCreate(
      context, glide, fragment.getLifecycle(), fm, fragment.isVisible());
}

@Deprecated
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull Activity activity) {
  if (Util.isOnBackgroundThread()) {
    return get(activity.getApplicationContext());
  } else if (activity instanceof FragmentActivity) {
    return get((FragmentActivity) activity);
  } else {
    assertNotDestroyed(activity);
    frameWaiter.registerSelf(activity);
    android.app.FragmentManager fm = activity.getFragmentManager();
    return fragmentGet(activity, fm, /* parentHint= */ null, isActivityVisible(activity));
  }
}
  • 1. 如果with方法在子线程运行或者context是Application,则会走到getApplicationManager(context),这里会创建一个全局的Glide,不会随着控件生命周期销毁
  • 2. 如果是主线程
    • 2.1:context是FragmentActivity/Fragment,利用Lifecycle来将生命周期与RequestManager绑定
    • 2.2:context是Activity,添加一个无视图的RequestManagerFragment来将生命周期与RequestManager绑定
  • 注意:之前版本的Glide与Activity生命周期绑定是通过添加一个无视图的RequestManagerFragment来同步,新版本增加了LifecycleRequestManagerRetriever类借助Lifecycle来管理FragmentActivity/Fragment生命周期,之前的Activity(非FragmentActivity)由于并没有集成Lifecycle,还是借助RequestManagerFragment,主要目的是将图片获取与页面生命周期相关联,只有在视图展示阶段进行图片下载

image.png

2.2 requestManager.load(url)相关源码

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

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

@NonNull
@CheckResult
public <ResourceType> RequestBuilder<ResourceType> as(
    @NonNull Class<ResourceType> resourceClass) {
  return new RequestBuilder<>(glide, this, resourceClass, context);
}
// RequestBuilder.java
@NonNull
@Override
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable String string) {
  return loadGeneric(string);
}

@NonNull
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
  if (isAutoCloneEnabled()) {
    return clone().loadGeneric(model);
  }
  this.model = model;
  isModelSet = true;
  // 最终返回this,即RequestBuilder对象
  return selfOrThrowIfLocked();
}
  • 流程很简单就是构造一个RequestBuilder并设置请求的mode(url),并记录url已设置的状态

image.png

3. requestBuiler.into(iv)相关源码

3.1 requestBuiler.into(...)

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

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

  return into(
      // 位置1(下面分析) 
      glideContext.buildImageViewTarget(view, transcodeClass),
      /* targetListener= */ null,
      requestOptions,
      Executors.mainThreadExecutor());
}

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

  // 位置2(下面分析) 
  // 建立图片网络请求
  Request request = buildRequest(target, targetListener, options, callbackExecutor);

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

  requestManager.clear(target);
  target.setRequest(request);
  // 位置3(下面分析)
  // 追踪请求
  requestManager.track(target, request);

  return target;
}
  • 看下上面位置1处的glideContext.buildImageViewTarget(view, transcodeClass)

3.2 glideContext.buildImageViewTarget(...)

// GlideContext.java
@NonNull
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
    @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
  return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
// ImageViewTargetFactory.java
public class ImageViewTargetFactory {
  @NonNull
  @SuppressWarnings("unchecked")
  public <Z> ViewTarget<ImageView, Z> buildTarget(
      @NonNull ImageView view, @NonNull Class<Z> clazz) {
    // 返回展示Bitmap/Drawable资源的目标对象
    if (Bitmap.class.equals(clazz)) {
      return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
    } else if (Drawable.class.isAssignableFrom(clazz)) {
      return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
    } else {
      throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
  }
}
  • Glide内部维护了两种target,一种BitmapImageViewTarget,一种DrawableImageViewTarget
  • 接着看下上面 3.1 的位置2 buildRequest(target, targetListener, options, callbackExecutor)

3.3 requestBuilder.buildRequest(...)

// RequestBuilder.java
private Request buildRequest(
    Target<TranscodeType> target,
    @Nullable RequestListener<TranscodeType> targetListener,
    BaseRequestOptions<?> requestOptions,
    Executor callbackExecutor) {
  return buildRequestRecursive(
      /* requestLock= */ new Object(),
      target,
      targetListener,
      /* parentCoordinator= */ null,
      transitionOptions,
      requestOptions.getPriority(),
      requestOptions.getOverrideWidth(),
      requestOptions.getOverrideHeight(),
      requestOptions,
      callbackExecutor);
}


private Request buildRequestRecursive(
    Object requestLock,
    Target<TranscodeType> target,
    @Nullable RequestListener<TranscodeType> targetListener,
    @Nullable RequestCoordinator parentCoordinator,
    TransitionOptions<?, ? super TranscodeType> transitionOptions,
    Priority priority,
    int overrideWidth,
    int overrideHeight,
    BaseRequestOptions<?> requestOptions,
    Executor callbackExecutor) {
  ErrorRequestCoordinator errorRequestCoordinator = null;
  if (errorBuilder != null) {
    // 创建图片请求错误时处理对象ErrorRequestCoordinator
    errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, parentCoordinator);
    parentCoordinator = errorRequestCoordinator;
  }

  // 递归建立缩略图请求
  Request mainRequest =
      buildThumbnailRequestRecursive(
          requestLock,
          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();
  }

  // 图片请求错误时展示的图片请求(使用了error()的api)
  Request errorRequest =
      errorBuilder.buildRequestRecursive(
          requestLock,
          target,
          targetListener,
          errorRequestCoordinator,
          errorBuilder.transitionOptions,
          errorBuilder.getPriority(),
          errorOverrideWidth,
          errorOverrideHeight,
          errorBuilder,
          callbackExecutor);
  errorRequestCoordinator.setRequests(mainRequest, errorRequest);
  return errorRequestCoordinator;
}


private Request buildThumbnailRequestRecursive(
    Object requestLock,
    Target<TranscodeType> target,
    RequestListener<TranscodeType> targetListener,
    @Nullable RequestCoordinator parentCoordinator,
    TransitionOptions<?, ? super TranscodeType> 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<?, ? super TranscodeType> 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(requestLock, parentCoordinator);
    // 完整图片请求
    Request fullRequest =
        obtainRequest(
            requestLock,
            target,
            targetListener,
            requestOptions,
            coordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            callbackExecutor);
    isThumbnailBuilt = true;
    // 递归生成缩略图请求
    Request thumbRequest =
        thumbnailBuilder.buildRequestRecursive(
            requestLock,
            target,
            targetListener,
            coordinator,
            thumbTransitionOptions,
            thumbPriority,
            thumbOverrideWidth,
            thumbOverrideHeight,
            thumbnailBuilder,
            callbackExecutor);
    isThumbnailBuilt = false;
    // 能够同时加载缩略图和正常的图的请求
    coordinator.setRequests(fullRequest, thumbRequest);
    return coordinator;
  } else if (thumbSizeMultiplier != null) {
    // 当设置了缩略的比例thumbSizeMultiplier(0 ~ 1)时,无需递归建立缩略图请求
    ThumbnailRequestCoordinator coordinator =
        new ThumbnailRequestCoordinator(requestLock, parentCoordinator);
    Request fullRequest =
        obtainRequest(
            requestLock,
            target,
            targetListener,
            requestOptions,
            coordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            callbackExecutor);
    BaseRequestOptions<?> thumbnailOptions =
        requestOptions.clone().sizeMultiplier(thumbSizeMultiplier);

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

    coordinator.setRequests(fullRequest, thumbnailRequest);
    return coordinator;
  } else {
    // 没有缩略图需求时,直接获取一个正常图请求
    return obtainRequest(
        requestLock,
        target,
        targetListener,
        requestOptions,
        parentCoordinator,
        transitionOptions,
        priority,
        overrideWidth,
        overrideHeight,
        callbackExecutor);
  }
}


private Request obtainRequest(
    Object requestLock,
    Target<TranscodeType> target,
    RequestListener<TranscodeType> targetListener,
    BaseRequestOptions<?> requestOptions,
    RequestCoordinator requestCoordinator,
    TransitionOptions<?, ? super TranscodeType> transitionOptions,
    Priority priority,
    int overrideWidth,
    int overrideHeight,
    Executor callbackExecutor) {
  // 最终承载请求的是SingleRequest
  return SingleRequest.obtain(
      context,
      glideContext,
      requestLock,
      model,
      transcodeClass,
      requestOptions,
      overrideWidth,
      overrideHeight,
      priority,
      target,
      targetListener,
      requestListeners,
      requestCoordinator,
      glideContext.getEngine(),
      transitionOptions.getTransitionFactory(),
      callbackExecutor);
}
  • 看下这个SingleRequest.obtain(...),其实就是创建了一个SingleRequest对象,
// SingleRequest.java
public static <R> SingleRequest<R> obtain(
    Context context,
    GlideContext glideContext,
    Object requestLock,
    Object model,
    Class<R> transcodeClass,
    BaseRequestOptions<?> requestOptions,
    int overrideWidth,
    int overrideHeight,
    Priority priority,
    Target<R> target,
    RequestListener<R> targetListener,
    @Nullable List<RequestListener<R>> requestListeners,
    RequestCoordinator requestCoordinator,
    Engine engine,
    TransitionFactory<? super R> animationFactory,
    Executor callbackExecutor) {
  return new SingleRequest<>(
      context,
      glideContext,
      requestLock,
      model,
      transcodeClass,
      requestOptions,
      overrideWidth,
      overrideHeight,
      priority,
      target,
      targetListener,
      requestListeners,
      requestCoordinator,
      engine,
      animationFactory,
      callbackExecutor);
}
  • 由此可见上面3.1的位置2最终返回的是一个SingleRequest,接着分析下3.1的位置3 requestManager.track(target, request);

3.4 requestManager.track(target, request)

// RequestManager.java
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
  // 加入一个target目标集合(Set)
  targetTracker.track(target);
  requestTracker.runRequest(request);
}
  • 看下requestTracker.runRequest(request)
// RequestTracker.java
public void runRequest(@NonNull Request request) {
  requests.add(request);
  if (!isPaused) {
    // 非暂停状态开始请求
    request.begin();
  } else {
    // 否则清空请求,添加到请求意图队列
    request.clear();
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      Log.v(TAG, "Paused, delaying request");
    }
    pendingRequests.add(request);
  }
}
  • 真正开始执行请求的方法是request.begin()即上面返回的SingleRequest.begin()

3.5 SingleRequest.begin()

// SingleRequest.java
@Override
public void begin() {
  synchronized (requestLock) {
    assertNotCallingCallbacks();
    stateVerifier.throwIfRecycled();
    startTime = LogTime.getLogTime();
    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, /* isLoadedFromAlternateCacheKey= */ false);
      return;
    }

    experimentalNotifyRequestStarted(model);

    cookie = GlideTrace.beginSectionAsync(TAG);
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      // 当使用override() API为图片指定了一个固定的宽高时直接执行onSizeReady
      // 最终的核心处理位于onSizeReady
      onSizeReady(overrideWidth, overrideHeight);
    } else {
      // 根据imageView的宽高算出图片的宽高,最终也会走到onSizeReady
      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));
    }
  }
}


@Override
public void onSizeReady(int width, int height) {
  stateVerifier.throwIfRecycled();
  synchronized (requestLock) {
    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是一个负责加载、管理活跃和缓存资源的引擎类
    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));
    }
  }
}
  • 接着看下负责加载、管理活跃和缓存资源的引擎类engine.load(...)

3.6 engine.load(...)

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

  EngineKey key =
      keyFactory.buildKey(
          model,
          signature,
          width,
          height,
          transformations,
          resourceClass,
          transcodeClass,
          options);

  EngineResource<?> memoryResource;
  synchronized (this) {
    // 先从内存读取
    memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

    if (memoryResource == null) {
      // 不存在
      return waitForExistingOrStartNewJob(
          glideContext,
          model,
          signature,
          width,
          height,
          resourceClass,
          transcodeClass,
          priority,
          diskCacheStrategy,
          transformations,
          isTransformationRequired,
          isScaleOnlyOrNoTransform,
          options,
          isMemoryCacheable,
          useUnlimitedSourceExecutorPool,
          useAnimationPool,
          onlyRetrieveFromCache,
          cb,
          callbackExecutor,
          key,
          startTime);
    }
  }

  // 回调相关 
  cb.onResourceReady(
      memoryResource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
  return null;
}


@Nullable
private EngineResource<?> loadFromMemory(
    EngineKey key, boolean isMemoryCacheable, long startTime) {
  if (!isMemoryCacheable) {
    return null;
  }
  // 从弱引用中查找
  EngineResource<?> active = loadFromActiveResources(key);
  if (active != null) {
    if (VERBOSE_IS_LOGGABLE) {
      logWithTimeAndKey("Loaded resource from active resources", startTime, key);
    }
    return active;
  }
  // 没有就从缓存中获取
  EngineResource<?> cached = loadFromCache(key);
  if (cached != null) {
    if (VERBOSE_IS_LOGGABLE) {
      logWithTimeAndKey("Loaded resource from cache", startTime, key);
    }
    return cached;
  }

  return null;
}
  • 可见显示从ActiveResources弱引用中获取,没有再从缓存MemoryCache中获取,都获取不到的话会执行waitForExistingOrStartNewJob(...)

3.7 engine.waitForExistingOrStartNewJob(...)

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

  EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
  if (current != null) {
    current.addCallback(cb, callbackExecutor);
    if (VERBOSE_IS_LOGGABLE) {
      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, callbackExecutor);
  engineJob.start(decodeJob);

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


public synchronized void start(DecodeJob<R> decodeJob) {
  this.decodeJob = decodeJob;
  GlideExecutor executor =
      decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
  executor.execute(decodeJob);
}
  • 最终Engine(引擎)类内部会执行到自身的start方法,它会根据不同的配置采用不同的线程池使用diskCacheExecutor/sourceUnlimitedExecutor/animationExecutor/sourceExecutor来执行最终的解码任务decodeJob,直接看decodeJob.run()

3.8 decodeJob.run()

// DecodeJob.java
@Override
public void run() {
...
    runWrapped();
...
}


private void runWrapped() {
  switch (runReason) {
    case INITIALIZE:
      stage = getNextStage(Stage.INITIALIZE);
      currentGenerator = getNextGenerator();
      // 内部会调用startNext()
      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() {
  // 完整情况下,会异步依次生成这里的ResourceCacheGenerator、DataCacheGenerator和SourceGenerator对象,
  // 并在之后执行其中的startNext()
  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(RunReason.SWITCH_TO_SOURCE_SERVICE);
      return;
    }
  }
  if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
    notifyFailed();
  }
}


private Stage getNextStage(Stage current) {
  switch (current) {
    case INITIALIZE:
      return diskCacheStrategy.decodeCachedResource()
          ? Stage.RESOURCE_CACHE
          : getNextStage(Stage.RESOURCE_CACHE);
    case RESOURCE_CACHE: // 对应ResourceCacheGenerator执行器
      return diskCacheStrategy.decodeCachedData()
          ? Stage.DATA_CACHE
          : getNextStage(Stage.DATA_CACHE);
    case DATA_CACHE:  // 对应DataCacheGenerator执行器
      return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
    case SOURCE: // 对应SourceGenerator执行器
    case FINISHED:
      return Stage.FINISHED;
    default:
      throw new IllegalArgumentException("Unrecognized stage: " + current);
  }
}
  • ResourceCacheGenerator:缓存中获取数据,这个数据是被修改过的降采样缓存
  • DataCacheGenerator:也是缓存中获取数据,这个数据是没有被修改的网路请求元数据
  • SourceGenerator:这个执行器执行的任务才真正是用于网络请求数据
  • 通过getNextGenerator()返回的DataFetcherGenerator对象都会去执行runGenerators(),执行顺序为: ResourceCacheGenerator -> DataCacheGenerator -> SourceGenerator

3.9 SourceGenerator.startNext()

// SourceGenerator.java
@Override
public boolean startNext() {
  // dataToCache数据不为空的话缓存到硬盘
  if (dataToCache != null) {
    Object data = dataToCache;
    dataToCache = null;
    try {
      boolean isDataInCache = cacheData(data);
      if (!isDataInCache) {
        return true;
      }
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "Failed to properly rewind or write data to cache", e);
      }
    }
  }

  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;
      // 加载
      startNextLoad(loadData);
    }
  }
  return started;
}


List<LoadData<?>> getLoadData() {
  if (!isLoadDataSet) {
    isLoadDataSet = true;
    loadData.clear();
    List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
    for (int i = 0, size = modelLoaders.size(); i < size; i++) {
      ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
      // 这里最终是通过HttpGlideUrlLoader的buildLoadData获取到实际的loadData对象
      LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
      if (current != null) {
        loadData.add(current);
      }
    }
  }
  return loadData;
}


private void startNextLoad(final LoadData<?> toStart) {
  loadData.fetcher.loadData(
      helper.getPriority(),
      new DataCallback<Object>() {
        @Override
        public void onDataReady(@Nullable Object data) {
          if (isCurrentRequest(toStart)) {
             // 位置1
             // 请求成功会执行的
            onDataReadyInternal(toStart, data);
          }
        }

        @Override
        public void onLoadFailed(@NonNull Exception e) {
          if (isCurrentRequest(toStart)) {
            onLoadFailedInternal(toStart, e);
          }
        }
      });
}

3.10 HttpGlideUrlLoader.buildLoadData(...)

// HttpGlideUrlLoader.java
@Override
public LoadData<InputStream> 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是正真负责网络请求图片数据的类
  return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
}
  • 从上面3.9中的startNextLoad(loadData)方法看,最终会执行HttpUrlFetcher.loadData()

3.11 HttpUrlFetcher.loadData()

// HttpUrlFetcher.java
@Override
public void loadData(
    @NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
  long startTime = LogTime.getLogTime();
  try {
    // loadDataWithRedirects内部是使用的HttpURLConnection进行的网络请求
    InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
    // 请求成功后会回调onDataReady
    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<String, String> headers) throws HttpException {
  ...

  urlConnection = buildAndConfigureConnection(url, headers);

  try {
    urlConnection.connect();
    stream = urlConnection.getInputStream();
  } catch (IOException e) {
    throw new HttpException(
        "Failed to connect or obtain data", getHttpStatusCodeOrInvalid(urlConnection), e);
  }

  if (isCancelled) {
    return null;
  }

  final int statusCode = getHttpStatusCodeOrInvalid(urlConnection);
  if (isHttpOk(statusCode)) {
    return getStreamForSuccessfulRequest(urlConnection);
  } else if (isHttpRedirect(statusCode)) {
    String redirectUrlString = urlConnection.getHeaderField(REDIRECT_HEADER_FIELD);
    if (TextUtils.isEmpty(redirectUrlString)) {
      throw new HttpException("Received empty or null redirect url", statusCode);
    }
    URL redirectUrl;
    try {
      redirectUrl = new URL(url, redirectUrlString);
    } catch (MalformedURLException e) {
      throw new HttpException("Bad redirect url: " + redirectUrlString, statusCode, e);
    }
    cleanup();
    return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
  } else if (statusCode == INVALID_STATUS_CODE) {
    throw new HttpException(statusCode);
  } else {
    try {
      throw new HttpException(urlConnection.getResponseMessage(), statusCode);
    } catch (IOException e) {
      throw new HttpException("Failed to get a response message", statusCode, e);
    }
  }
}


private HttpURLConnection buildAndConfigureConnection(URL url, Map<String, String> headers)
    throws HttpException {
  HttpURLConnection urlConnection;
  try {
    urlConnection = connectionFactory.build(url);
  } catch (IOException e) {
    throw new HttpException("URL.openConnection threw", /* statusCode= */ 0, e);
  }
  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);
  urlConnection.setInstanceFollowRedirects(false);
  return urlConnection;
}
  • 在HttpUrlFetcher.loadData()方法的loadDataWithRedirects()里面,Glide通过原生的HttpURLConnection进行请求后,并调用getStreamForSuccessfulRequest()方法获取到了最终的图片流.
  • 获取到流之后会执行到3.9中位置1处的的onDataReadyInternal(toStart, data)

3.12 SourceGenerator.onDataReadyInternal(toStart, data)

// SourceGenerator.java
@Synthetic
void onDataReadyInternal(LoadData<?> loadData, Object data) {
  DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
  if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
    dataToCache = data;
    cb.reschedule();
  } else {
    cb.onDataFetcherReady(
        loadData.sourceKey,
        data,
        loadData.fetcher,
        loadData.fetcher.getDataSource(),
        originalKey);
  }
}
  • 接着会用DecodeJob.onDataFetcherReady(...)
// DecodeJob.java
@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;
  this.isLoadingFromAlternateCacheKey = sourceKey != decodeHelper.getCacheKeys().get(0);

  if (Thread.currentThread() != currentThread) {
    reschedule(RunReason.DECODE_DATA);
  } else {
    GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
    try {
      // 数据解码
      decodeFromRetrievedData();
    } finally {
      GlideTrace.endSection();
    }
  }
}

3.13 DecodeJob.decodeFromRetrievedData()

// DecodeJob.java
private void decodeFromRetrievedData() {
  ...
  Resource<R> resource = null;
  try {
    // 将数据解码成Resource
    resource = decodeFromData(currentFetcher, currentData, currentDataSource);
  } catch (GlideException e) {
    e.setLoggingDetails(currentAttemptingKey, currentDataSource);
    throwables.add(e);
  }
  if (resource != null) {
    notifyEncodeAndRelease(resource, currentDataSource, isLoadingFromAlternateCacheKey);
  } else {
    runGenerators();
  }
}


private void notifyEncodeAndRelease(
    Resource<R> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
  GlideTrace.beginSection("DecodeJob.notifyEncodeAndRelease");
  try {
    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, isLoadedFromAlternateCacheKey);

    stage = Stage.ENCODE;
    try {
      if (deferredEncodeManager.hasResourceToEncode()) {
        deferredEncodeManager.encode(diskCacheProvider, options);
      }
    } finally {
      if (lockedResource != null) {
        lockedResource.unlock();
      }
    }
    onEncodeComplete();
  } finally {
    GlideTrace.endSection();
  }
}


private void notifyComplete(
    Resource<R> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
  setNotifiedOrThrow();
  callback.onResourceReady(resource, dataSource, isLoadedFromAlternateCacheKey);
}
  • 使用decodeFromData(...)将请求数据解码成Resource,最终执行notifyEncodeAndRelease() -> notifyComplete() -> notifyComplete() -> callback.onResourceReady()

3.14 EngineJob.onResourceReady(...)

// EngineJob.java
public void onResourceReady(
    Resource<R> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
  synchronized (this) {
    this.resource = resource;
    this.dataSource = dataSource;
    this.isLoadedFromAlternateCacheKey = isLoadedFromAlternateCacheKey;
  }
  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 = engineResourceFactory.build(resource, isCacheable, key, resourceListener);
    hasResource = true;
    copy = cbs.copy();
    incrementPendingCallbacks(copy.size() + 1);

    localKey = key;
    localResource = engineResource;
  }

  engineJobListener.onEngineJobComplete(this, localKey, localResource);

  for (final ResourceCallbackAndExecutor entry : copy) {
    // 关键方法
    entry.executor.execute(new CallResourceReady(entry.cb));
  }
  decrementPendingCallbacks();
}
  • 最终会执行CallResourceReady.run()
// EngineJob.java
private class CallResourceReady implements Runnable {
 ...

  @Override
  public void run() {
    synchronized (cb.getLock()) {
      synchronized (EngineJob.this) {
        if (cbs.contains(cb)) {
          engineResource.acquire();
          callCallbackOnResourceReady(cb);
          removeCallback(cb);
        }
        decrementPendingCallbacks();
      }
    }
  }
}


@Synthetic
@GuardedBy("this")
void callCallbackOnResourceReady(ResourceCallback cb) {
  try {
    cb.onResourceReady(engineResource, dataSource, isLoadedFromAlternateCacheKey);
  } catch (Throwable t) {
    throw new CallbackException(t);
  }
}
  • 最终执行到SingleRequest.onResourceReady(...)

3.15 SingleRequest.onResourceReady(...)

// SingleRequest.java
@Override
public void onResourceReady(
    Resource<?> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
  stateVerifier.throwIfRecycled();
  Resource<?> toRelease = null;
  try {
    synchronized (requestLock) {
      loadStatus = null;
      if (resource == null) {
       ...
        onLoadFailed(exception);
        return;
      }

      Object received = resource.get();
      if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
        toRelease = resource;
        this.resource = null;
        ...
        onLoadFailed(exception);
        return;
      }

      if (!canSetResource()) {
        toRelease = resource;
        this.resource = null;
        status = Status.COMPLETE;
        GlideTrace.endSectionAsync(TAG, cookie);
        return;
      }

      onResourceReady(
          (Resource<R>) resource, (R) received, dataSource, isLoadedFromAlternateCacheKey);
    }
  } finally {
    if (toRelease != null) {
      engine.release(toRelease);
    }
  }
}


@GuardedBy("requestLock")
private void onResourceReady(
    Resource<R> resource, R result, DataSource dataSource, boolean isAlternateCacheKey) {
  boolean isFirstResource = isFirstReadyResource();
  status = Status.COMPLETE;
  this.resource = resource;
 ...

  notifyRequestCoordinatorLoadSucceeded();

  isCallingCallbacks = true;
  try {
    boolean anyListenerHandledUpdatingTarget = false;
    if (requestListeners != null) {
      for (RequestListener<R> listener : requestListeners) {
        anyListenerHandledUpdatingTarget |=
            listener.onResourceReady(result, model, target, dataSource, isFirstResource);
      }
    }
    anyListenerHandledUpdatingTarget |=
        targetListener != null
            && targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);

    if (!anyListenerHandledUpdatingTarget) {
      Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
      // 关键方法
      target.onResourceReady(result, animation);
    }
  } finally {
    isCallingCallbacks = false;
  }

  GlideTrace.endSectionAsync(TAG, cookie);
}
  • SingleRequest.onResourceReady() -> onResourceReady()重载方法 -> target.onResourceReady(result, animation),这里的target其实就是我们在into方法中建立的那个BitmapImageViewTarget,看到BitmapImageViewTarget类,我们并没有发现onResourceReady(...),是直接从其父类ImageViewTarget继承过来的,直接看ImageViewTarget.onResourceReady(...)

3.16 ImageViewTarget.onResourceReady(...)

// ImageViewTarget.java
@Override
public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> 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);
  • 最终调用了setResource(resource)这个抽象方法,具体实现还是回到其子类BitmapImageViewTarget/DrawableImageViewTarget
// BitmapImageViewTarget.java
@Override
protected void setResource(Bitmap resource) {
  view.setImageBitmap(resource);
}
  • 最终将resouce设置到对应的ImageView上

3.17 三级缓存的使用

  • 如果存在内存缓存,则去activeResources(弱引用的对象)中取解码后的数据
  • 如果activeResources中没有对应的缓存,则去cache缓存中获取,如找到则直接返回cache数据,并将缓存数据写入activeResources中,删除cache中的缓存数据,
  • 如果还没有,则在调用网络请求前,去磁盘中获取,磁盘中获取的数据是图片原数据,需要经过解码处理才能被控件使用,磁盘如果还没有,才会去网络中请求数据。

3.18 流程图

requestBuilder.into(iv)流程.png