注:本文基于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. 执行解码任务