一、整体概述
在 Android 开发中,图片加载是一个常见且重要的功能。Glide 作为一款强大的图片加载库,因其高效、灵活和易于使用的特点,被广泛应用于各种 Android 应用中。Glide 的配置与初始化模块是整个库的基础,它允许开发者根据不同的需求对 Glide 进行定制化设置,如缓存策略、图片解码格式、自定义组件等。本文将深入 Glide 源码,详细剖析其配置与初始化模块的实现原理和工作流程。
二、配置与初始化模块概述
2.1 模块的作用
Glide 的配置与初始化模块主要负责以下几个方面的工作:
- 全局配置:允许开发者对 Glide 的各种行为进行全局配置,如设置缓存大小、自定义组件等。
- 组件注册 :开发者可以通过该模块注册自定义的组件,如
ModelLoader
、ResourceDecoder
等,以支持新的数据源和图片格式。 - 生命周期管理:确保 Glide 与应用的生命周期进行正确的绑定,避免内存泄漏。
2.2 核心组件
该模块的核心组件包括:
GlideBuilder
:用于构建Glide
实例,提供了一系列方法来设置 Glide 的各种配置。GlideModule
(在 Glide 4.x 及以后版本为AppGlideModule
和LibraryGlideModule
):提供了一种在应用启动时配置 Glide 的方式,开发者可以在GlideModule
中注册自定义的组件、修改默认配置等。Glide
:Glide 库的核心类,负责管理图片加载请求、缓存、线程池等。
2.3 整体架构
Glide 配置与初始化模块的整体架构可以分为以下几个层次:
- 应用层:开发者在应用代码中调用 Glide 的初始化方法,并进行相关配置。
- 配置层 :
GlideBuilder
和GlideModule
负责接收开发者的配置信息,并进行相应的设置。 - 核心层 :
Glide
类根据配置信息进行初始化,创建各种组件和服务。
三、GlideBuilder 源码分析
3.1 类定义及属性
java
java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.Engine;
import com.bumptech.glide.load.engine.cache.DiskCache;
import com.bumptech.glide.load.engine.cache.DiskCacheFactory;
import com.bumptech.glide.load.engine.cache.MemoryCache;
import com.bumptech.glide.load.engine.cache.M.cache.MemorySizeCalculator;
import com.bumptech.glide.load.engine.executor.GlideExecutor;
import com.bumptech.glide.manager.ConnectivityMonitorFactory;
import com.bumptech.glide.manager.DefaultConnectivityMonitorFactory;
import com.bumptech.glide.manager.Lifecycle;
import com.bumptech.glide.manager.RequestManagerRetriever;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.ViewTarget;
import com.bumptech.glide.util.Preconditions;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
// GlideBuilder 类,用于构建 Glide 实例
public final class GlideBuilder {
// 应用上下文
private final Context context;
// 内存缓存工厂
private MemoryCache.Factory memoryCacheFactory;
// 磁盘缓存工厂
private DiskCache.Factory diskCacheFactory;
// 引擎工厂
private Engine.Factory engineFactory;
// 解码格式
private DecodeFormat decodeFormat = DecodeFormat.DEFAULT;
// 默认的请求选项
private RequestOptions defaultRequestOptions = new RequestOptions();
// 连接监控工厂
private ConnectivityMonitorFactory connectivityMonitorFactory;
// 后台线程池
private GlideExecutor sourceExecutor;
// 磁盘缓存线程池
private GlideExecutor diskCacheExecutor;
// 动画帧线程池
private GlideExecutor animationExecutor;
// 生命周期
private Lifecycle lifecycle;
// 请求管理器检索器
private RequestManagerRetriever.RequestManagerFactory requestManagerFactory;
// 视图目标的默认布局参数
private ViewTarget.LayoutParamsFactory defaultLayoutParamsFactory;
// 注册表,用于注册各种组件
private final Registry registry = new Registry();
// 全局日志级别
private int logLevel = android.util.Log.DEBUG;
// 动画处理类
private Handler mainHandler;
// 内存大小计算器
private MemorySizeCalculator memorySizeCalculator;
// 组件清单解析器
private final List<com.bumptech.glide.module.GlideModule> manifestModules = new ArrayList<>();
// 自定义的 Glide 模块
private com.bumptech.glide.module.GlideModule customModule;
}
在 GlideBuilder
类中,定义了一系列属性,用于存储 Glide 的各种配置信息。这些属性包括内存缓存工厂、磁盘缓存工厂、引擎工厂、解码格式、默认请求选项等。通过这些属性,开发者可以对 Glide 的各个方面进行定制化配置。
3.2 构造函数
java
java
/**
* 构造函数,初始化 GlideBuilder 实例
*
* @param context 应用上下文
*/
GlideBuilder(@NonNull Context context) {
// 保存应用上下文
this.context = context.getApplicationContext();
}
构造函数接收一个 Context
对象,并将其转换为应用上下文进行保存。这是为了避免因传入的 Context
生命周期过短而导致的内存泄漏问题。
3.3 配置方法
3.3.1 内存缓存配置
java
java
/**
* 设置内存缓存工厂
*
* @param memoryCacheFactory 内存缓存工厂
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setMemoryCache(@NonNull MemoryCache.Factory memoryCacheFactory) {
// 检查传入的内存缓存工厂是否为空
this.memoryCacheFactory = Preconditions.checkNotNull(memoryCacheFactory);
return this;
}
setMemoryCache
方法用于设置内存缓存工厂。开发者可以通过该方法自定义内存缓存的实现,例如使用自定义的 LruResourceCache
或其他内存缓存策略。
3.3.2 磁盘缓存配置
java
java
/**
* 设置磁盘缓存工厂
*
* @param diskCacheFactory 磁盘缓存工厂
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setDiskCache(@NonNull DiskCache.Factory diskCacheFactory) {
// 检查传入的磁盘缓存工厂是否为空
this.diskCacheFactory = Preconditions.checkNotNull(diskCacheFactory);
return this;
}
setDiskCache
方法用于设置磁盘缓存工厂。开发者可以通过该方法自定义磁盘缓存的实现,例如使用自定义的 DiskLruCacheWrapper
或其他磁盘缓存策略。
3.3.3 引擎配置
java
java
/**
* 设置引擎工厂
*
* @param engineFactory 引擎工厂
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setEngine(@NonNull Engine.Factory engineFactory) {
// 检查传入的引擎工厂是否为空
this.engineFactory = Preconditions.checkNotNull(engineFactory);
return this;
}
setEngine
方法用于设置引擎工厂。引擎是 Glide 的核心组件之一,负责管理图片的加载、缓存和资源回收等操作。开发者可以通过该方法自定义引擎的实现。
3.3.4 解码格式配置
java
java
/**
* 设置解码格式
*
* @param decodeFormat 解码格式
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setDecodeFormat(@NonNull DecodeFormat decodeFormat) {
// 检查传入的解码格式是否为空
this.decodeFormat = Preconditions.checkNotNull(decodeFormat);
return this;
}
setDecodeFormat
方法用于设置图片的解码格式。不同的解码格式会影响图片的质量和内存占用,开发者可以根据实际需求选择合适的解码格式。
3.3.5 默认请求选项配置
java
java
/**
* 设置默认的请求选项
*
* @param defaultRequestOptions 默认请求选项
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setDefaultRequestOptions(@NonNull RequestOptions defaultRequestOptions) {
// 检查传入的默认请求选项是否为空
this.defaultRequestOptions = Preconditions.checkNotNull(defaultRequestOptions);
return this;
}
setDefaultRequestOptions
方法用于设置默认的请求选项。默认请求选项会应用到所有的图片加载请求中,开发者可以通过该方法设置一些通用的请求参数,如占位图、错误图等。
3.3.6 连接监控工厂配置
java
java
/**
* 设置连接监控工厂
*
* @param factory 连接监控工厂
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setConnectivityMonitorFactory(@NonNull ConnectivityMonitorFactory factory) {
// 检查传入的连接监控工厂是否为空
this.connectivityMonitorFactory = Preconditions.checkNotNull(factory);
return this;
}
setConnectivityMonitorFactory
方法用于设置连接监控工厂。连接监控工厂用于创建连接监控器,监控网络连接状态的变化,以便在网络连接可用时自动恢复图片加载任务。
3.3.7 线程池配置
java
java
/**
* 设置后台线程池
*
* @param sourceExecutor 后台线程池
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setSourceExecutor(@NonNull GlideExecutor sourceExecutor) {
// 检查传入的后台线程池是否为空
this.sourceExecutor = Preconditions.checkNotNull(sourceExecutor);
return this;
}
/**
* 设置磁盘缓存线程池
*
* @param diskCacheExecutor 磁盘缓存线程池
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setDiskCacheExecutor(@NonNull GlideExecutor diskCacheExecutor) {
// 检查传入的磁盘缓存线程池是否为空
this.diskCacheExecutor = Preconditions.checkNotNull(diskCacheExecutor);
return this;
}
/**
* 设置动画帧线程池
*
* @param animationExecutor 动画帧线程池
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setAnimationExecutor(@NonNull GlideExecutor animationExecutor) {
// 检查传入的动画帧线程池是否为空
this.animationExecutor = Preconditions.checkNotNull(animationExecutor);
return this;
}
这些方法分别用于设置后台线程池、磁盘缓存线程池和动画帧线程池。不同的线程池用于执行不同类型的任务,如后台线程池用于执行网络请求和图片解码任务,磁盘缓存线程池用于执行磁盘缓存的读写任务,动画帧线程池用于执行动画帧的加载和处理任务。
3.3.8 其他配置方法
java
java
/**
* 设置生命周期
*
* @param lifecycle 生命周期
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setLifecycle(@NonNull Lifecycle lifecycle) {
// 检查传入的生命周期是否为空
this.lifecycle = Preconditions.checkNotNull(lifecycle);
return this;
}
/**
* 设置请求管理器工厂
*
* @param factory 请求管理器工厂
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setRequestManagerFactory(@NonNull RequestManagerRetriever.RequestManagerFactory factory) {
// 检查传入的请求管理器工厂是否为空
this.requestManagerFactory = Preconditions.checkNotNull(factory);
return this;
}
/**
* 设置视图目标的默认布局参数工厂
*
* @param factory 视图目标的默认布局参数工厂
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setDefaultLayoutParamsFactory(@NonNull ViewTarget.LayoutParamsFactory factory) {
// 检查传入的视图目标的默认布局参数工厂是否为空
this.defaultLayoutParamsFactory = Preconditions.checkNotNull(factory);
return this;
}
/**
* 设置全局日志级别
*
* @param logLevel 全局日志级别
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setLogLevel(int logLevel) {
this.logLevel = logLevel;
return this;
}
/**
* 设置动画处理类
*
* @param mainHandler 动画处理类
* @return GlideBuilder 实例,用于链式调用
*/
@NonNull
public GlideBuilder setMainHandler(@NonNull Handler mainHandler) {
// 检查传入的动画处理类是否为空
this.mainHandler = Preconditions.checkNotNull(mainHandler);
return this;
}
这些方法分别用于设置生命周期、请求管理器工厂、视图目标的默认布局参数工厂、全局日志级别和动画处理类。开发者可以通过这些方法对 Glide 的各个方面进行更细致的配置。
3.4 构建 Glide 实例
java
java
/**
* 构建 Glide 实例
*
* @return Glide 实例
*/
@NonNull
public Glide build(@NonNull Context context) {
// 如果未设置后台线程池,使用默认的后台线程池
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 (memoryCacheFactory == null) {
memoryCacheFactory = new LruResourceCache.Factory(memorySizeCalculator.getMemoryCacheSize());
}
// 如果未设置磁盘缓存工厂,使用默认的磁盘缓存工厂
if (diskCacheFactory == null) {
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}
// 如果未设置引擎工厂,使用默认的引擎工厂
if (engineFactory == null) {
engineFactory = new Engine.Factory(diskCacheFactory, diskCacheExecutor, sourceExecutor);
}
// 如果未设置连接监控工厂,使用默认的连接监控工厂
if (connectivityMonitorFactory == null) {
connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
}
// 如果未设置动画处理类,创建一个默认的动画处理类
if (mainHandler == null) {
mainHandler = new Handler(Looper.getMainLooper());
}
// 创建引擎实例
Engine engine = engineFactory.build(
memoryCacheFactory.build(),
diskCacheExecutor,
sourceExecutor,
animationExecutor,
isActiveResourceRetentionAllowed);
// 创建请求管理器检索器
RequestManagerRetriever requestManagerRetriever = new RequestManagerRetriever(requestManagerFactory);
// 创建 Glide 实例
Glide glide = new Glide(
context,
engine,
memoryCacheFactory.build(),
diskCacheFactory,
registry,
animationExecutor,
memorySizeCalculator,
connectivityMonitorFactory,
logLevel,
defaultRequestOptions.lock(),
defaultTransitionOptions,
requestManagerRetriever,
mainHandler,
defaultLayoutParamsFactory);
// 注册所有的 Glide 模块
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.registerComponents(context, glide, registry);
}
if (customModule != null) {
customModule.registerComponents(context, glide, registry);
}
return glide;
}
build
方法用于构建 Glide
实例。在该方法中,会检查各个配置项是否已经设置,如果未设置,则使用默认的配置。然后根据配置信息创建引擎、请求管理器检索器等组件,并最终创建 Glide
实例。最后,会注册所有的 GlideModule
,以便对 Glide
进行进一步的配置和扩展。
四、GlideModule 源码分析
4.1 GlideModule 概述
在 Glide 4.x 及以后版本中,GlideModule
被拆分为 AppGlideModule
和 LibraryGlideModule
。AppGlideModule
用于在应用级别进行配置,而 LibraryGlideModule
用于在库级别进行配置。
4.2 AppGlideModule 源码分析
4.2.1 类定义及属性
java
java
import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
// 标记该类为 AppGlideModule
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
// 可以在这里添加自定义的配置方法和属性
}
AppGlideModule
是一个抽象类,开发者需要创建一个继承自 AppGlideModule
的子类,并使用 @GlideModule
注解进行标记。
4.2.2 主要方法
java
java
@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
// 在这里可以对 GlideBuilder 进行配置
builder.setMemoryCache(new LruResourceCache(10 * 1024 * 1024)); // 设置内存缓存大小为 10MB
builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, 50 * 1024 * 1024)); // 设置磁盘缓存大小为 50MB
}
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
// 在这里可以注册自定义的组件
registry.append(MyModel.class, InputStream.class, new MyModelLoader.Factory());
}
@Override
public boolean isManifestParsingEnabled() {
// 是否启用组件清单解析
return false;
}
applyOptions
方法:用于对GlideBuilder
进行配置,开发者可以在该方法中设置内存缓存、磁盘缓存、解码格式等配置信息。registerComponents
方法:用于注册自定义的组件,如ModelLoader
、ResourceDecoder
等。通过该方法,开发者可以扩展 Glide 的功能,支持新的数据源和图片格式。isManifestParsingEnabled
方法:用于控制是否启用组件清单解析。在 Glide 4.x 及以后版本中,建议将该方法返回false
,以避免组件清单解析带来的性能开销。
4.3 LibraryGlideModule 源码分析
4.3.1 类定义及属性
java
java
import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.LibraryGlideModule;
// 标记该类为 LibraryGlideModule
@GlideModule
public class MyLibraryGlideModule extends LibraryGlideModule {
// 可以在这里添加自定义的配置方法和属性
}
LibraryGlideModule
也是一个抽象类,开发者需要创建一个继承自 LibraryGlideModule
的子类,并使用 @GlideModule
注解进行标记。
4.3.2 主要方法
java
java
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
// 在这里可以注册自定义的组件
registry.append(MyModel.class, InputStream.class, new MyModelLoader.Factory());
}
LibraryGlideModule
主要用于在库级别注册自定义的组件。与 AppGlideModule
不同的是,LibraryGlideModule
没有 applyOptions
方法,因为库级别通常不进行全局配置,而是专注于组件的注册。
五、Glide 初始化流程分析
5.1 初始化入口
在应用代码中,通常通过以下方式初始化 Glide:
java
java
GlideBuilder builder = new GlideBuilder(context);
Glide glide = builder.build(context);
或者使用 Glide.get(context)
方法,该方法会在内部调用 GlideBuilder
进行初始化:
java
java
Glide glide = Glide.get(context);
5.2 初始化流程
- 创建 GlideBuilder 实例 :在初始化过程中,首先会创建一个
GlideBuilder
实例,用于接收和保存配置信息。 - 配置 GlideBuilder :开发者可以通过
GlideBuilder
的各种配置方法,对 Glide 的内存缓存、磁盘缓存、引擎、解码格式等进行配置。 - 注册 GlideModule :在
build
方法中,会注册所有的GlideModule
,包括AppGlideModule
和LibraryGlideModule
。在GlideModule
中,开发者可以对GlideBuilder
进行进一步的配置,或者注册自定义的组件。 - 创建核心组件 :根据配置信息,
build
方法会创建引擎、请求管理器检索器等核心组件。 - 创建 Glide 实例 :最后,
build
方法会创建Glide
实例,并将配置信息和核心组件传递给Glide
实例。
5.3 初始化流程的源码分析
java
java
// Glide 类中的 get 方法
public static Glide get(@NonNull Context context) {
// 检查传入的上下文是否为空
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
// 获取应用上下文
Context applicationContext = context.getApplicationContext();
// 获取组件清单解析器
List<com.bumptech.glide.module.GlideModule> manifestModules = new ManifestParser(applicationContext).parse();
// 创建 GlideBuilder 实例
GlideBuilder builder = new GlideBuilder(applicationContext);
// 创建 AppGlideModule 实例
AppGlideModule appGlideModule = new GeneratedAppGlideModuleImpl();
// 应用 AppGlideModule 中的配置
appGlideModule.applyOptions(applicationContext, builder);
// 注册 LibraryGlideModule 中的组件
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.registerComponents(applicationContext, builder, builder.getRegistry());
}
// 注册 AppGlideModule 中的组件
appGlideModule.registerComponents(applicationContext, builder, builder.getRegistry());
// 构建 Glide 实例
glide = builder.build(applicationContext);
}
}
}
return glide;
}
在 get
方法中,会首先检查 Glide
实例是否已经创建。如果未创建,则会进行以下操作:
- 获取应用上下文。
- 使用
ManifestParser
解析组件清单,获取所有的LibraryGlideModule
。 - 创建
GlideBuilder
实例。 - 创建
AppGlideModule
实例,并调用其applyOptions
方法对GlideBuilder
进行配置。 - 注册所有
LibraryGlideModule
和AppGlideModule
中的组件。 - 调用
GlideBuilder
的build
方法构建Glide
实例。
六、自定义配置和组件注册
6.1 自定义内存缓存
开发者可以通过 GlideBuilder
的 setMemoryCache
方法自定义内存缓存。以下是一个自定义内存缓存的示例:
java
java
// 自定义内存缓存工厂
class MyMemoryCacheFactory implements MemoryCache.Factory {
@Override
public MemoryCache build() {
return new LruResourceCache(20 * 1024 * 1024); // 设置内存缓存大小为 20MB
}
}
// 在应用代码中使用自定义内存缓存
GlideBuilder builder = new GlideBuilder(context);
builder.setMemoryCache(new MyMemoryCacheFactory());
Glide glide = builder.build(context);
在这个示例中,我们创建了一个自定义的内存缓存工厂 MyMemoryCacheFactory
,并在 build
方法中返回一个 LruResourceCache
实例,设置其大小为 20MB。然后通过 GlideBuilder
的 setMemoryCache
方法使用该自定义内存缓存工厂。
6.2 自定义磁盘缓存
开发者可以通过 GlideBuilder
的 setDiskCache
方法自定义磁盘缓存。以下是一个自定义磁盘缓存的示例:
java
java
// 自定义磁盘缓存工厂
class MyDiskCacheFactory implements DiskCache.Factory {
@Override
public DiskCache build() {
return DiskLruCacheWrapper.create(new File(context.getExternalCacheDir(), "my_cache"),