Glide 的 with 源码分析
以下分析的所有源码,都只是部分源码,只为了总体流程分析。
Glide 显示网络图片最简单的代码如下:
Glide.with(this).load(url).into(mImageView);
在这里,我先展示一张整体的加载流程图:

接下来,我们一步步分析 with 的源码。
// 传入View
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
// 传入 Fragment
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getContext()).get(fragment);
}
// 传入 FragmentActivity
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
// 传入 Activity
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
// 传入 Context
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
共有 5 个重载的 with 方法,分别在不同的场景使用,但是所有的方法都会调用 getRetriever 方法。
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
return Glide.get(context).getRequestManagerRetriever();
}
接下来,重点分析 get 方法。
public static Glide get(@NonNull Context context) {
if (glide == null) {
// 获取Glide注解自动生成的一个Module配置器
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
该方法是一个双检锁单例模式,首先调用 getAnnotationGeneratedGlideModules 方法来获取 Glide 注解自动生成的一个配置器类,主要是利用反射机制来构建一个配置类实例,这个类是在注解生成器里面生成的。
private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules(Context context) {
GeneratedAppGlideModule result = null;
Class<GeneratedAppGlideModule> clazz =
(Class<GeneratedAppGlideModule>)
Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
result =
clazz.getDeclaredConstructor(Context.class).newInstance(context.getApplicationContext());
return result;
}
然后调用 checkAndInitializeGlide 来检查并初始化 Glide 。
private static void checkAndInitializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
isInitializing = true;
initializeGlide(context, generatedAppGlideModule);
isInitializing = false;
}
重点在 initializeGlide 方法。
private static void initializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
// 创建了一个构建器对象 GlideBuilder ,默认的一些参数和配置
initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}
接着又调用了一个重载的 initializeGlide 方法,这才是真正初始化 Glide 的方法。
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
Context applicationContext = context.getApplicationContext();
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
// 1.如果没有注解生成器,或者开启了 Manifest 的检索
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
// 2.编译时自动生成的类中,包含了需要排除的GlideModule,逐个将其移除
if (annotationGeneratedModule != null
&& !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
while (iterator.hasNext()) {
com.bumptech.glide.module.GlideModule current = iterator.next();
if (!excludedModuleClasses.contains(current.getClass())) {
continue;
}
iterator.remove();
}
}
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory()
: null;
builder.setRequestManagerFactory(factory);
// 3.下面的代码是回调 Module 的 applyOptions 方法来配置属性
// 用户自定义配置的属性就生效了
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
// 4.实例化 Glide
Glide glide = builder.build(applicationContext);
// 5.下面的代码是回调 Module 的 registerComponents 方法来注册组件
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.registerComponents(applicationContext, glide, glide.registry);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
applicationContext.registerComponentCallbacks(glide);
// 6.赋值给单例对象
Glide.glide = glide;
}
该初始化方法主要做的工作如下:
- 检索 Manifest 文件配置的 GlideModule 。
- 移除重复的 GlideModule 。
- 回调 GlideModule 的 applyOptions 方法来配置自定义的属性。
- 调用 build 方法来构建 Glide 实例。
- 回调 GlideModule 的 registerComponents 方法来注册组件。
- 把 glide 实例赋值给单例对象。
在第 4 步中会构建 Glide 实例,整个框架非常重要的初始化内容都在这里实现,下面我们重点来看一下这个 build 方法。
Glide build(@NonNull Context context) {
if (sourceExecutor == null) {
// 创建资源加载请求器,是一个线程池,用于加载源数据(URL等)
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) {
// 创建 bitmap 资源缓存池,用于资源的回收和缓存,避免由于大量创建和回收 bitmap 导致内存抖动
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) {
// 磁盘缓存器,默认为 APP 内部私密目录
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);
}
// 请求索引器
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory);
// 创建 Glide,注意传入的参数
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
isLoggingRequestOriginsEnabled,
isImageDecoderEnabledForBitmaps,
hardwareBitmapFdLimit);
}
}
这个方法主要是实例化一些对象,真正实例化 Glide 对象是最后面的new Glide() ,那么我们继续分析 Glide 的构造方法。由于该方法代码量非常多,故省略大量代码,只显示核心逻辑。
Glide(
@NonNull Context context,
@NonNull Engine engine,
@NonNull MemoryCache memoryCache,
@NonNull BitmapPool bitmapPool,
@NonNull ArrayPool arrayPool,
@NonNull RequestManagerRetriever requestManagerRetriever,
@NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
int logLevel,
@NonNull RequestOptionsFactory defaultRequestOptionsFactory,
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
@NonNull List<RequestListener<Object>> defaultRequestListeners,
boolean isLoggingRequestOriginsEnabled,
boolean isImageDecoderEnabledForBitmaps,
int hardwareBitmapFdLimit) {
// 赋值
this.engine = engine;
this.bitmapPool = bitmapPool;
this.arrayPool = arrayPool;
this.memoryCache = memoryCache;
this.requestManagerRetriever = requestManagerRetriever;
this.connectivityMonitorFactory = connectivityMonitorFactory;
this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;
final Resources resources = context.getResources();
// 新建注册器
registry = new Registry();
registry.register(new DefaultImageHeaderParser());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
registry.register(new ExifInterfaceImageHeaderParser());
}
List<ImageHeaderParser> imageHeaderParsers = registry.getImageHeaderParsers();
// 创建解码器
ByteBufferGifDecoder byteBufferGifDecoder =
new ByteBufferGifDecoder(context, imageHeaderParsers, bitmapPool, arrayPool);
ResourceDecoder<ParcelFileDescriptor, Bitmap> parcelFileDescriptorVideoDecoder =
VideoDecoder.parcel(bitmapPool);
ResourceDecoder<ByteBuffer, Bitmap> byteBufferBitmapDecoder;
ResourceDecoder<InputStream, Bitmap> streamBitmapDecoder;
if (isImageDecoderEnabledForBitmaps && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
streamBitmapDecoder = new InputStreamBitmapImageDecoderResourceDecoder();
byteBufferBitmapDecoder = new ByteBufferBitmapImageDecoderResourceDecoder();
} else {
Downsampler downsampler =
new Downsampler(
registry.getImageHeaderParsers(),
resources.getDisplayMetrics(),
bitmapPool,
arrayPool);
byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool);
}
ResourceDrawableDecoder resourceDrawableDecoder = new ResourceDrawableDecoder(context);
// 创建数据转换器
ResourceLoader.StreamFactory resourceLoaderStreamFactory =
new ResourceLoader.StreamFactory(resources);
ResourceLoader.UriFactory resourceLoaderUriFactory = new ResourceLoader.UriFactory(resources);
ResourceLoader.FileDescriptorFactory resourceLoaderFileDescriptorFactory =
new ResourceLoader.FileDescriptorFactory(resources);
ResourceLoader.AssetFileDescriptorFactory resourceLoaderAssetFileDescriptorFactory =
new ResourceLoader.AssetFileDescriptorFactory(resources);
BitmapEncoder bitmapEncoder = new BitmapEncoder(arrayPool);
// 创建转码器
BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();
GifDrawableBytesTranscoder gifDrawableBytesTranscoder = new GifDrawableBytesTranscoder();
ContentResolver contentResolver = context.getContentResolver();
// 注册各个类型的解码器和编码器
registry
.append(ByteBuffer.class, new ByteBufferEncoder())
.append(InputStream.class, new StreamEncoder(arrayPool))
// 这里省略大量注册代码
.register(
Drawable.class,
byte[].class,
new DrawableBytesTranscoder(
bitmapPool, bitmapBytesTranscoder, gifDrawableBytesTranscoder))
.register(GifDrawable.class, byte[].class, gifDrawableBytesTranscoder);
// 创建图片显示目标对象工厂
ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
// 创建 GlideContext 对象,注意传入的参数
glideContext =
new GlideContext(
context,
arrayPool,
registry,
imageViewTargetFactory,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
engine,
isLoggingRequestOriginsEnabled,
logLevel);
}
该方法主要是初始化模型转换器、解码器、转码器和编码器,并对各种类型在注册表一一进行注册。
Glide 的加载流程可以概括为以下流程:
model(数据源)-->data(转换数据)-->decode(解码)-->transformed(缩放)-->transcoded(转码)-->encoded(编码保存到本地)
这个流程非常重要,后面的源码分析就是一步步对流程的每个步骤进行分析。注册表里注册的各种模型转换器、解码器、转码器和编码器,都分别在各个步骤起作用。
到这里,Glide 的 get 方法终于分析完成,那么让我们回到 getRetriever 方法,在实例化 Glide后,会调用 getRequestManagerRetriever 方法来获取 RequestManagerRetriever 对象。
public RequestManagerRetriever getRequestManagerRetriever() {
return requestManagerRetriever;
}
回到最开始的 with 方法可知,后面会根据不会场景来调用 RequestManagerRetriever 的重载 get 方法。接下来我们分析最常用的入参为 Activity 的重载方法。
public RequestManager get(@NonNull Activity activity) {
// 是否后台线程
if (Util.isOnBackgroundThread()) {
// 获取 getApplicationContext,调用重载的 get 方法
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
接下来,重点分析 fragmentGet 方法:
private RequestManager fragmentGet(
@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
// 获取一个命名为FRAGMENT_TAG的fragment,如不存在,则新建一个RequestManagerFragment,并添加到当前页面中。
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
// 创建 RequestManager,RequestManager 会把自己放进生命周期监听器集合里
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
// 把 RequestManager 设置到当前的 fragment 对象里
current.setRequestManager(requestManager);
}
return requestManager;
}
Glide 是通过在页面中添加一个 Fragment 来动态监听页面的创建和销毁,从而达到依赖页面生命周期,动态管理请求的目的。
那么到底是怎样通过 Fragment 来实现的生命周期监听呢?下面详细分析一下。
首先,看一下 RequestManagerFragment 的构造方法,如下:
public RequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
在构造方法中,构建了一个生命周期监听器对象 ActivityFragmentLifecycle 。然后会在 Fragment 的各个生命周期中调用该监听器的对应的方法。
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
registerFragmentWithRoot(activity);
} catch (IllegalStateException e) {
// OnAttach can be called after the activity is destroyed, see #497.
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Unable to register fragment with root", e);
}
}
}
@Override
public void onDetach() {
super.onDetach();
unregisterFragmentWithRoot();
}
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
那么,重点就在于这个监听器对象了,源码如下:
class ActivityFragmentLifecycle implements Lifecycle {
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
主要是将各个 LifecycleListener 对象添加到集合里面,然后在不同的生命周期来遍历处理对应的生命周期方法。那么这个 LifecycleListener 又有谁呢?其实就包括 RequestManager 对象。我们来看一下 RequestManager 里面添加到监听器集合里的代码。
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
// 把自己添加到监听器里,来监听加载的整个生命周期
lifecycle.addListener(this);
}
// 添加网络监听器
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
private final Runnable addSelfToLifecycle =
new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
由此可知,RequestManager 和 ConnectivityMonitor 都被添加到了生命周期监听。由于每个 with 方法都会实例化一个 RequestManager 对象 和 ConnectivityMonitor 对象,而且这两个对象添加到了生命周期监听,并被设置到了对应的 Fragment 对象里面,所以每个请求都会跟随 fragment 的生命周期。
最后会返回一个 RequestManager 对象,即 Glide 的 with 对象最终会得到一个 RequestManager 对象。
如果传入的是 applicationContext ,会调用如下方法来获取 RequestManager 对象 :
private RequestManager getApplicationManager(@NonNull Context context) {
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
// 构造一个 ApplicationLifecycle 对象传入
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
至此,总结一下 Glide 的初始化流程:
- 获取 Glide 注解自动生成的一个配置器类。
- 检索 Manifest 文件配置的 GlideModule 。
- 移除重复的 GlideModule 。
- 回调 GlideModule 的 applyOptions 方法来配置自定义的属性。
- 调用 build 方法来构建 Glide 实例。
- 回调 GlideModule 的 registerComponents 方法来注册组件。
- 把 glide 实例赋值给单例对象。
- 在 RequestManagerRetriever 的重载 get 方法中建立生命周期监听,并返回一个RequestManager。
在上述的第 5 步,build 方法处理的内容如下:
- 新建线程池
- 新建图片缓存池和缓存池
- 新建内存缓存管理器
- 新建默认本地缓存管理器
- 新建请求引擎Engine
- 新建RequestManger检索器
- 在 Glide 的构造方法中初始化模型转换器、解码器、转码器和编码器,并对各种类型在注册表一一进行注册。