Android Glide 图片加载库源码流程浅析

7 阅读13分钟

注:本文基于Glide 4.16版本

通常来说,使用Glide.with(context).load(model).into(imageView)就可以加载图片了,具体的执行流程是怎样的呢?

一、with方法基本流程

1. with重载方法

首先,让我们来看看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 with(activity.getApplicationContext());
}

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

@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment) {
  Activity activity = fragment.getActivity();
  Preconditions.checkNotNull(activity, DESTROYED_ACTIVITY_WARNING);
  return with(activity.getApplicationContext());
}

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

@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  // Context could be null for other reasons (ie the user passes in null), but in practice it will
  // only occur due to errors with the Fragment lifecycle.
  Preconditions.checkNotNull(context, DESTROYED_ACTIVITY_WARNING);
  return Glide.get(context).getRequestManagerRetriever();
}

可以看到,with方法内部会通过getRetriever方法拿到RequestManagerRetriever对象,然后再调用RequestManagerRetriever的get方法得到RequestManager

2. Glide.get(context)方法

我们接着来看看Glide.get(context)方法里面都做了些什么

@NonNull
// Double checked locking is safe here.
@SuppressWarnings("GuardedBy")
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;
}

可以看到,使用了双重校验单例来获取Glide对象,继续查看checkAndInitializeGlide方法

@GuardedBy("Glide.class")
@VisibleForTesting
static void checkAndInitializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  // In the thread running initGlide(), one or more classes may call Glide.get(context).
  // Without this check, those calls could trigger infinite recursion.
  if (isInitializing) {
    throw new IllegalStateException(
        "Glide has been called recursively, this is probably an internal library error!");
  }
  isInitializing = true;
  try {
    // 重点
    initializeGlide(context, generatedAppGlideModule);
  } finally {
    isInitializing = false;
  }
}

checkAndInitializeGlide 里面会调用 initializeGlide 方法进行初始化

@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) {
  ...
  Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
  applicationContext.registerComponentCallbacks(glide);
  Glide.glide = glide;
}

可以看到,通过建造者模式去构建glide对象

3. GlideBuilder.build方法

里面会创建sourceExecutor、diskCacheExecutor、animationExecutor、memorySizeCalculator、bitmapPool、engine等对象

// GlideBuilder.java

@NonNull
Glide build(
    @NonNull Context context,
    List<GlideModule> manifestModules,
    AppGlideModule annotationGeneratedGlideModule) {
  if (sourceExecutor == null) {
    sourceExecutor = GlideExecutor.newSourceExecutor();
  }

  if (diskCacheExecutor == null) {
    diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
  }

  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();
    }
  }

  if (arrayPool == null) {
    arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
  }

  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 requestManagerRetriever =
      new RequestManagerRetriever(requestManagerFactory);

  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptionsFactory,
      defaultTransitionOptions,
      defaultRequestListeners,
      manifestModules,
      annotationGeneratedGlideModule,
      experiments);
}

4. RequestManagerRetriever.get方法

RequestManagerRetriever.get有多个重载方法,会根据参数类型和调用线程做出不同决策

// 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)) {
    if (context instanceof FragmentActivity) {
      return get((FragmentActivity) context);
    } else if (context instanceof ContextWrapper
        && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
      return get(((ContextWrapper) context).getBaseContext());
    }
  }
  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
@NonNull
public RequestManager get(@NonNull Activity activity) {
  return get(activity.getApplicationContext());
}

@NonNull
public RequestManager get(@NonNull View view) {
  if (Util.isOnBackgroundThread()) {
    return get(view.getContext().getApplicationContext());
  }

  Preconditions.checkNotNull(view);
  Preconditions.checkNotNull(
      view.getContext(), "Unable to obtain a request manager for a view without a Context");
  Activity activity = findActivity(view.getContext());
  // The view might be somewhere else, like a service.
  if (activity == null) {
    return get(view.getContext().getApplicationContext());
  }

  if (activity instanceof FragmentActivity) {
    Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
    return fragment != null ? get(fragment) : get((FragmentActivity) activity);
  }

  // Standard Fragments.
  return get(view.getContext().getApplicationContext());
}

5. LifecycleRequestManagerRetriever.getOrCreate方法

RequestManager对象是通过lifecycleRequestManagerRetriever.getOrCreate获取的

// LifecycleRequestManagerRetriever.java

RequestManager getOrCreate(
    Context context,
    Glide glide,
    final Lifecycle lifecycle,
    FragmentManager childFragmentManager,
    boolean isParentVisible) {
  Util.assertMainThread();
  RequestManager result = getOnly(lifecycle);
  if (result == null) {
    // 传入lifecycle
    LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);
    result =
        factory.build(
            glide,
            glideLifecycle,
            new SupportRequestManagerTreeNode(childFragmentManager),
            context);
    lifecycleToRequestManager.put(lifecycle, result);
    glideLifecycle.addListener(
        new LifecycleListener() {
          @Override
          public void onStart() {}

          @Override
          public void onStop() {}

          @Override
          public void onDestroy() {
            lifecycleToRequestManager.remove(lifecycle);
          }
        });
        
    if (isParentVisible) {
      result.onStart();
    }
  }
  return result;
}

6. RequestManagerFactory工厂方法

通过RequestManagerFactory 创建了一个RequestManager对象

RequestManagerRetriever.java

/** Used internally to create {@link RequestManager}s. */
public interface RequestManagerFactory {
  @NonNull
  RequestManager build(
      @NonNull Glide glide,
      @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode requestManagerTreeNode,
      @NonNull Context context);
}

private static final RequestManagerFactory DEFAULT_FACTORY =
    new RequestManagerFactory() {
      @NonNull
      @Override
      public RequestManager build(
          @NonNull Glide glide,
          @NonNull Lifecycle lifecycle,
          @NonNull RequestManagerTreeNode requestManagerTreeNode,
          @NonNull Context context) {
        return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
      }
    };

7.RequestManager构造方法

RequestManager本身实现LifecycleListener接口,并执行lifecycle.addListener(this),完成生命周期绑定

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

public RequestManager(
    @NonNull Glide glide,
    @NonNull Lifecycle lifecycle,
    @NonNull RequestManagerTreeNode treeNode,
    @NonNull Context context) {
  this(
      glide,
      lifecycle,
      treeNode,
      new RequestTracker(),
      glide.getConnectivityMonitorFactory(),
      context);
}

// Our usage is safe here.
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
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));

  glide.registerRequestManager(this);

  if (Util.isOnBackgroundThread()) {
    Util.postOnUiThread(addSelfToLifecycle);
  } else {
    lifecycle.addListener(this);
  }
  lifecycle.addListener(connectivityMonitor);

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

8. RequestManager生命周期回调方法

RequestManager相关生命周期回调方法具体如下

@Override
public synchronized void onStart() {
  resumeRequests();
  targetTracker.onStart();
}

@Override
public synchronized void onStop() {
  targetTracker.onStop();
  if (clearOnStop) {
    clearRequests();
  } else {
    pauseRequests();
  }
}

@Override
public synchronized void onDestroy() {
  targetTracker.onDestroy();
  clearRequests();
  requestTracker.clearRequests();
  lifecycle.removeListener(this);
  lifecycle.removeListener(connectivityMonitor);
  Util.removeCallbacksOnUiThread(addSelfToLifecycle);
  glide.unregisterRequestManager(this);
}

二、load()方法基本流程

RequestManager.load() 是 Glide API 的核心入口,它负责将各种数据模型统一转换为可管理的加载请求。这个方法的设计体现了 Glide 灵活的数据源支持类型安全的构建器模式

1. RequestManager.load()重载方法

load方法实际上是一系列重载方法,支持不同类型的数据源:

public class RequestManager implements LifecycleListener {
    
    // 1. 加载网络/本地图片路径
    public RequestBuilder<Drawable> load(@Nullable String string) {
        return asDrawable().load(string);
    }
    
    // 2. 加载Uri
    public RequestBuilder<Drawable> load(@Nullable Uri uri) {
        return asDrawable().load(uri);
    }
    
    // 3. 加载File
    public RequestBuilder<Drawable> load(@Nullable File file) {
        return asDrawable().load(file);
    }
    
    // 4. 加载资源ID
    public RequestBuilder<Drawable> load(@RawRes @DrawableRes @Nullable Integer resourceId) {
        return asDrawable().load(resourceId);
    }
    
    // 5. 加载URL对象
    public RequestBuilder<Drawable> load(@Nullable URL url) {
        return asDrawable().load(url);
    }
    
    // 6. 加载字节数组
    public RequestBuilder<Drawable> load(@Nullable byte[] model) {
        return asDrawable().load(model);
    }
    
    // 7. 加载任意对象(泛型方法)
    public <ResourceType> RequestBuilder<ResourceType> load(@Nullable Object model) {
        return as(ResourceType.class).load(model);
    }
}

2. load方法内部类型推断与转换

// 当你调用:Glide.with(context).load("https://example.com/image.jpg")
// 实际执行流程:
public RequestBuilder<Drawable> load(@Nullable String string) {
    // 步骤1: 确定资源类型为Drawable
    return asDrawable()  //  创建指定类型的RequestBuilder
             .load(string); //  设置数据模型
}

// asDrawable()的实现
public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
}

// 通用的as()方法
public <ResourceType> RequestBuilder<ResourceType> as(
    @NonNull Class<ResourceType> resourceClass) {
    
    // 创建对应资源类型的RequestBuilder
    return new RequestBuilder<>(
        glide,                     // Glide单例
        this,                      // RequestManager自身
        resourceClass,             // 目标资源类型(Drawable.class)
        context                    // 上下文
    );
}

3. RequestBuilder的初始化

RequestBuilder 是真正的请求建造者,它存储了请求的所有配置:

// We only override the method to change the return type, not the functionality.
@SuppressLint("CheckResult")
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
protected RequestBuilder(
    @NonNull Glide glide,
    RequestManager requestManager,
    Class<TranscodeType> transcodeClass,
    Context context) {
  this.glide = glide;
  this.requestManager = requestManager;
  this.transcodeClass = transcodeClass;
  this.context = context;
  this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
  this.glideContext = glide.getGlideContext();

  initRequestListeners(requestManager.getDefaultRequestListeners());
  apply(requestManager.getDefaultRequestOptions());
}

4. RequestBuilder.load重载方法

@NonNull
@CheckResult
@SuppressWarnings("unchecked")
@Override
public RequestBuilder<TranscodeType> load(@Nullable Object model) {
  return loadGeneric(model);
}

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

@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable Bitmap bitmap) {
  return loadGeneric(bitmap).apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}

@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable Drawable drawable) {
  return loadGeneric(drawable).apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}

@NonNull
@Override
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable String string) {
  return loadGeneric(string);
}

@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable Uri uri) {
  return maybeApplyOptionsResourceUri(uri, loadGeneric(uri));
}

private RequestBuilder<TranscodeType> maybeApplyOptionsResourceUri(
    @Nullable Uri uri, RequestBuilder<TranscodeType> requestBuilder) {
  if (uri == null || !ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
    return requestBuilder;
  }
  return applyResourceThemeAndSignature(requestBuilder);
}

private RequestBuilder<TranscodeType> applyResourceThemeAndSignature(
    RequestBuilder<TranscodeType> requestBuilder) {
  return requestBuilder
      .theme(context.getTheme())
      .signature(AndroidResourceSignature.obtain(context));
}

@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable File file) {
  return loadGeneric(file);
}

@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@RawRes @DrawableRes @Nullable Integer resourceId) {
  return applyResourceThemeAndSignature(loadGeneric(resourceId));
}

@Deprecated
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable URL url) {
  return loadGeneric(url);
}

@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable byte[] model) {
  RequestBuilder<TranscodeType> result = loadGeneric(model);
  if (!result.isDiskCacheStrategySet()) {
    result = result.apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
  }
  if (!result.isSkipMemoryCacheSet()) {
    result = result.apply(skipMemoryCacheOf(true /*skipMemoryCache*/));
  }
  return result;
}

5.设计思想总结

RequestManager.load() 的设计体现了几个重要原则:

  • 单一职责load() 只负责接收和存储数据模型,不处理具体加载逻辑。
  • 延迟执行:配置在 into() 调用时才真正生效,支持完整的链式配置。
  • 类型安全:通过泛型确保资源类型的正确性。
  • 灵活扩展:支持任意数据模型类型(通过 ModelLoader 机制)。

理解 RequestManager.load() 的机制,就掌握了 Glide API 设计的精髓:通过流畅的构建器模式,将复杂的图片加载过程封装成简单、直观的链式调用,同时保持高度的可配置性和扩展性

三、into()方法基本流程

into()方法(在RequestBuilder类中)会做几件关键的事:

  • 构建Target:将ImageView包装成一个ImageViewTarget
  • 创建并启动请求:调用RequestManager.track(),最终会创建一个SingleRequest对象,并调用它的bedin()方法

1. into重载方法

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

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

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

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

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

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

  return target;
}

2. requestManager.track方法

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

/** Starts tracking the given request. */
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);
  }
}

3.SingleRequest.begin方法

@Override
public void begin() {
  synchronized (requestLock) {
    assertNotCallingCallbacks();
    stateVerifier.throwIfRecycled();
    startTime = LogTime.getLogTime();
    if (model == null) {
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        width = overrideWidth;
        height = overrideHeight;
      }
      onLoadFailed(new GlideException("Received null model"), logLevel);
      return;
    }

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

    if (status == Status.COMPLETE) {
      onResourceReady(
          resource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
      return;
    }

    experimentalNotifyRequestStarted(model);

    cookie = GlideTrace.beginSectionAsync(TAG);
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
    } else {
      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));
    }
  }
}

4. onSizeReady方法

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

5.Engine.load()方法

这里是整个加载流程的总调度中心,也是缓存检查的第一关

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;

  // 1. 创建唯一缓存Key:根据model、签名、ImageView宽高等参数生成EngineKey
  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;
}

6. loadFromMemory方法

@Nullable
private EngineResource<?> loadFromMemory(
    EngineKey key, boolean isMemoryCacheable, long startTime) {
  if (!isMemoryCacheable) {
    return null;
  }
  // 检查【活动资源缓存】(ActiveResources,弱引用)
  EngineResource<?> active = loadFromActiveResources(key);
  if (active != null) {
    if (VERBOSE_IS_LOGGABLE) {
      logWithTimeAndKey("Loaded resource from active resources", startTime, key);
    }
    return active;
  }
  检查【LRU内存缓存】(LruResourceCache)
  EngineResource<?> cached = loadFromCache(key);
  if (cached != null) {
    if (VERBOSE_IS_LOGGABLE) {
      logWithTimeAndKey("Loaded resource from cache", startTime, key);
    }
    return cached;
  }

  return null;
}

7. waitForExistingOrStartNewJob方法

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

  // 检查是否有相同Key的【正在执行的请求】
  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);
  // 启动DecodeJob
  engineJob.start(decodeJob);

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

关键点

  • 四级缓存在这里检查了两级(活动资源和内存缓存)
  • EngineKey是缓存的唯一标识,任何参数变化都会生成不同的Key
  • jobs 是一个存储正在执行任务的Map,用于请求合并

8. EngineJob:任务管理和线程切换器

EngineJob是一个管理和协调者,本身不执行加载,而是管理 DecodeJob的执行和回调

EngineJob.start(decodeJob)做了什么?

public synchronized void start(DecodeJob<R> decodeJob) {
  this.decodeJob = decodeJob;
  GlideExecutor executor =
      decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
  // 将decodeJob提交到线程池
  executor.execute(decodeJob);
}

EngineJob的核心职责

  • 持有DecodeJob:负责将DecodeJob提交到合适的线程池执行
  • 管理回调:一个EngineJob可能对应多个Target(请求合并)
  • 线程切换:当DecodeJob在子线程完成解码后,EngineJob负责将结果切换回主线程通知Target
  • 资源释放:通过EngineResource的引用计数机制,跟踪资源使用情况

9. DecodeJob:真正执行加载器

DecodeJob 实现了Runable接口,是真正执行加载,解码,变换的“工人”,它的run()方法是核心
DecodeJob.run()的主流程如下:

// We need to rethrow only CallbackException, but not other types of Throwables.
@SuppressWarnings("PMD.AvoidRethrowingException")
@Override
public void run() {
  GlideTrace.beginSectionFormat("DecodeJob#run(reason=%s, model=%s)", runReason, model);
  DataFetcher<?> localFetcher = currentFetcher;
  try {
    if (isCancelled) {
      notifyFailed();
      return;
    }
    // 核心方法:执行解码
    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();
  }
}

10. runWrapped方法

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

DecodeJob的三阶段工作流(DataFetcher)

DecodeJob内部使用三个DataFetcherGenerator来按顺序尝试获取数据:

  • ResourceCacheGenerator:尝试从磁盘缓存(转换后的图片)加载
  • DataCacheGenerator:尝试从磁盘缓存(原始数据)加载
  • SourceGenerator:最后从原始源(网络、文件等)加载

11. runGenerators方法

private void runGenerators() {
  currentThread = Thread.currentThread();
  startFetchTime = LogTime.getLogTime();
  boolean isStarted = false;
  while (!isCancelled
      && currentGenerator != null
      && !(isStarted = currentGenerator.startNext())) {
    // 如果当前Generator无法获取数据(未命中),则切换到下一个
    stage = getNextStage(stage);
    currentGenerator = getNextGenerator();

    if (stage == Stage.SOURCE) {
      // 当回退到SOURCE阶段时,需要切回主线程回调进度等
      reschedule(RunReason.SWITCH_TO_SOURCE_SERVICE);
      return;
    }
  }
  // We've run out of stages and generators, give up.
  if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
    notifyFailed();
  }

  // Otherwise a generator started a new load and we expect to be called back in
  // onDataFetcherReady.
}

12. startNext方法

SourceGenerator的网络加载过程: 当回退到SourceGenerator时,会通过ModelLoader加载网络数据

// Concurrent access isn't supported.
@SuppressWarnings({"NonAtomicOperationOnVolatileField", "NonAtomicVolatileUpdate"})
@Override
public boolean startNext() {
  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()) {
    // 通过ModelLoader获取DataFetcher
    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;
}

13. startNextLoad方法

private void startNextLoad(final LoadData<?> toStart) {
  loadData.fetcher.loadData(
      helper.getPriority(),
      new DataCallback<Object>() {
        // 加载完成的回调
        @Override
        public void onDataReady(@Nullable Object data) {
          if (isCurrentRequest(toStart)) {
            onDataReadyInternal(toStart, data);
          }
        }

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

14. onDataReadyInternal方法

@SuppressWarnings("WeakerAccess")
@Synthetic
void onDataReadyInternal(LoadData<?> loadData, Object data) {
  DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
  if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
    // 标记需要缓存
    dataToCache = data;
    cb.reschedule();
  } else {
    // 将数据交给DecodeJob继续处理(解码、变换)
    cb.onDataFetcherReady(
        loadData.sourceKey,
        data,
        loadData.fetcher,
        loadData.fetcher.getDataSource(),
        originalKey);
  }
}

15. DecodeJob.decodeFromRetrievedData方法

数据解码与变换流程: 当获取到数据后,会回到DecodeJob.decodeFromRetrievedData()

@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();
    }
  }
}

16. decodeFromRetrievedData方法

private void decodeFromRetrievedData() {
  if (Log.isLoggable(TAG, Log.VERBOSE)) {
    logWithTimeAndKey(
        "Retrieved data",
        startFetchTime,
        "data: "
            + currentData
            + ", cache key: "
            + currentSourceKey
            + ", fetcher: "
            + currentFetcher);
  }
  Resource<R> resource = null;
  try {
    // 核心解码方法
    resource = decodeFromData(currentFetcher, currentData, currentDataSource);
  } catch (GlideException e) {
    e.setLoggingDetails(currentAttemptingKey, currentDataSource);
    throwables.add(e);
  }
  if (resource != null) {
    // 通知EngineJob资源就绪
    notifyEncodeAndRelease(resource, currentDataSource, isLoadingFromAlternateCacheKey);
  } else {
    runGenerators();
  }
}

private <Data> Resource<R> decodeFromData(
    DataFetcher<?> fetcher, Data data, DataSource dataSource) throws GlideException {
  try {
    if (data == null) {
      return null;
    }
    long startTime = LogTime.getLogTime();
    Resource<R> result = decodeFromFetcher(data, dataSource);
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey("Decoded result " + result, startTime);
    }
    return result;
  } finally {
    fetcher.cleanup();
  }
}

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

private <Data, ResourceType> Resource<R> runLoadPath(
    Data data, DataSource dataSource, LoadPath<Data, ResourceType, R> path)
    throws GlideException {
  Options options = getOptionsWithHardwareConfig(dataSource);
  DataRewinder<Data> rewinder = glideContext.getRegistry().getRewinder(data);
  try {
    // ResourceType in DecodeCallback below is required for compilation to work with gradle.
    // 通过LoadPath执行解码链:解码 -> 变换 -> 转码
    return path.load(
        rewinder, options, width, height, new DecodeCallback<ResourceType>(dataSource));
  } finally {
    rewinder.cleanup();
  }
}

17. notifyEncodeAndRelease方法

回到EngineJob:结果分发

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

18. EngineJob.onResourceReady方法

@Override
public void onResourceReady(
    Resource<R> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
  synchronized (this) {
    this.resource = resource;
    this.dataSource = dataSource;
    this.isLoadedFromAlternateCacheKey = isLoadedFromAlternateCacheKey;
  }
  // 通知回调
  notifyCallbacksOfResult();
}

@SuppressWarnings({
  "WeakerAccess",
  "PMD.AvoidInstantiatingObjectsInLoops",
  "PMD.AccessorMethodGeneration"
})
@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();
}

19. into方法流程总结

into() 
→ SingleRequest.begin() 
→ Engine.load() 
    ├→ 命中活动资源 → 直接返回
    ├→ 命中内存缓存 → 直接返回  
    └→ 未命中 → 创建EngineJob & DecodeJob
        → EngineJob.start(decodeJob) 
        → 线程池执行DecodeJob.run()
        → DecodeJob.runWrapped()
            ├→ ResourceCacheGenerator (转换后缓存)
            ├→ DataCacheGenerator (原始数据缓存)
            └→ SourceGenerator (网络/文件)
                → ModelLoader.loadData() 
                → DataFetcher (如HttpUrlFetcher)
                → 获取数据后回调
        → 解码 → 变换 → 得到最终Resource
        → EngineJob.onResourceReady()
        → 切换主线程 → 回调Target → 显示图片
        → EngineResource引用计数管理

四、完整调用链总结

Glide.with(context)                    // 1. 获取RequestManager(绑定生命周期)
    .load(model)                       // 2. 创建RequestBuilder,设置数据模型
    .apply(options)                    // 3. 配置请求参数
    .thumbnail(...)                    // 4. 可选:设置缩略图
    .listener(...)                     // 5. 可选:设置监听器
    .into(target)                      // 6. 构建并提交请求,开始加载
        ↓
    RequestManager.track(target, request) // 7. 生命周期跟踪
        ↓
    Engine.load()                         // 8. 缓存检查与任务调度
        ↓
    DecodeJob.run()                       // 9. 执行解码任务