以下是一个结合实例的 Glide 3.7.0 关键源码文件解析,通过代码片段和流程分析,帮助理解其核心机制。
1. Glide.java:全局入口与初始化
核心作用:配置全局参数、注册组件(解码器、加载器等),提供单例入口。
关键代码分析
public class Glide {
private static volatile Glide glide; // 单例模式
// 初始化入口
public static Glide get(Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
Context applicationContext = context.getApplicationContext();
// 通过 GeneratedAppGlideModule 初始化(如应用自定义的 GlideModule)
glide = new GlideBuilder().build(applicationContext);
}
}
}
return glide;
}
// 构建 Glide 实例
Glide build(Context context) {
// 初始化线程池、注册默认组件(如 BitmapDecoder)
Engine engine = new Engine(
memoryCache,
diskCacheFactory,
diskCacheExecutor,
sourceExecutor
);
registry = new Registry();
// 注册默认组件:例如 ImageViewTarget 用于绑定到 ImageView
registry.register(ImageViewTarget.class, new ImageViewTargetFactory());
// 加载 GlideModule 配置(通过注解处理器生成)
GeneratedAppGlideModule module = getAnnotationGeneratedAppGlideModule();
if (module != null) {
module.applyOptions(context, new GlideBuilder());
}
return new Glide(context, engine, registry);
}
}
实例分析
-
自定义 GlideModule:
@GlideModule public class MyAppGlideModule extends AppGlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { // 配置磁盘缓存大小 builder.setDiskCache(new InternalCacheDiskCacheFactory(context, 100 * 1024 * 1024)); // 替换网络层为 OkHttp builder.setRegistry(registry -> registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory())); } }- Glide 初始化时会通过反射找到
@GlideModule注解的类,并调用applyOptions。
- Glide 初始化时会通过反射找到
2. RequestManager.java:生命周期管理与请求控制
核心作用:绑定 Activity/Fragment 生命周期,管理请求的启动、暂停、销毁。
关键代码分析
public class RequestManager implements LifecycleListener {
private final RequestTracker requestTracker = new RequestTracker();
private final Lifecycle lifecycle;
// 绑定生命周期
public void onStart() {
resumeRequests(); // 恢复请求
}
public void onStop() {
pauseRequests(); // 暂停请求
}
public void onDestroy() {
requestTracker.clearRequests(); // 销毁所有请求
}
// 发起请求的入口
public RequestBuilder<Drawable> load(String url) {
return asDrawable().load(url);
}
}
实例分析
-
生命周期绑定:
// 在 Activity 中绑定 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Glide 通过 RequestManagerRetriever 获取 RequestManager RequestManager requestManager = Glide.with(this); requestManager.load("http://example.com/image.jpg").into(imageView); } }Glide.with(Activity)会通过RequestManagerRetriever创建一个与 Activity 生命周期绑定的RequestManager。
3. Engine.java:资源加载引擎
核心作用:协调缓存、线程池、资源加载,是加载流程的核心调度者。
关键代码分析
public class Engine implements EngineJobListener {
// 核心方法:触发资源加载
public <R> LoadStatus load(...) {
// 1. 生成缓存 Key(基于 URL、尺寸、签名等参数)
EngineKey key = keyFactory.buildKey(model, width, height, transformations);
// 2. 检查活动缓存(Active Resources)
EngineResource<?> active = loadFromActiveResources(key);
if (active != null) {
return new LoadStatus(cb, active);
}
// 3. 检查内存缓存(Memory Cache)
EngineResource<?> cached = loadFromCache(key);
if (cached != null) {
return new LoadStatus(cb, cached);
}
// 4. 未命中缓存,创建 EngineJob 和 DecodeJob
EngineJob<R> engineJob = engineJobFactory.build(...);
DecodeJob<R> decodeJob = decodeJobFactory.build(...);
jobs.put(key, engineJob);
engineJob.addCallback(cb);
engineJob.start(decodeJob);
}
}
实例分析
- 缓存命中流程:
- 当加载图片时,
Engine首先通过EngineKey检查活动缓存(弱引用)。 - 如果未命中,再检查 LRU 内存缓存。
- 若仍未命中,最终创建
DecodeJob从磁盘或网络加载。
- 当加载图片时,
4. DecodeJob.java:解码任务调度
核心作用:负责数据获取、解码、转码,通过状态机管理任务流程。
关键代码分析
class DecodeJob<R> implements Runnable {
private DataFetcher<?> fetcher;
private ResourceDecoder<?, ?> decoder;
public void run() {
try {
// 状态机驱动流程
runWrapped();
} catch (Exception e) {
onLoadFailed(e);
}
}
private void runWrapped() {
switch (runReason) {
case INITIALIZE:
// 确定数据来源:缓存(RESOURCE_CACHE/DATA_CACHE)或原始数据(SOURCE)
stage = getNextStage(Stage.INITIALIZE);
currentGenerator = getNextGenerator();
runGenerators();
break;
case SWITCH_TO_SOURCE_SERVICE:
runGenerators(); // 切换到 SourceExecutor 执行网络请求
break;
}
}
// 实际加载数据的方法
private void runGenerators() {
while (!isCancelled && currentGenerator.startNext()) {
// 通过 DataFetcher 获取数据(例如 OkHttp 请求)
// 获取到数据后,通过 ResourceDecoder 解码
}
}
}
实例分析
- 网络图片加载流程:
DecodeJob根据Stage判断需要从网络加载(SOURCE)。- 使用
HttpUrlFetcher(默认)或自定义的OkHttpStreamFetcher发起网络请求。 - 获取到
InputStream后,通过BitmapDecoder解码为 Bitmap。
5. LruResourceCache.java:内存缓存实现
核心作用:基于 LRU 算法管理内存中的图片资源。
关键代码分析
public class LruResourceCache extends LruCache<Key, Resource<?>> implements MemoryCache {
@Override
protected int getSize(Resource<?> item) {
// 计算 Bitmap 占用的内存大小
return item.getSize();
}
@Override
public void trimMemory(int level) {
// 根据系统内存压力调整缓存大小
if (level >= android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
clearMemory();
}
}
}
实例分析
- 内存缓存策略:
- 默认最大内存为设备可用内存的 1/8。
- 当 Activity 销毁时,关联的图片资源会从活动缓存移入内存缓存。
6. DiskLruCacheWrapper.java:磁盘缓存实现
核心作用:基于 LRU 和文件锁管理磁盘缓存。
关键代码分析
public class DiskLruCacheWrapper implements DiskCache {
private final DiskLruCache diskLruCache;
@Override
public File get(Key key) {
String safeKey = safeKeyGenerator.getSafeKey(key);
// 生成缓存文件名(例如 "image_url_1234_0")
File file = new File(directory, safeKey + ".0");
return file.exists() ? file : null;
}
@Override
public void put(Key key, Writer writer) {
// 写入磁盘(通过 FileLocks 防止并发冲突)
DiskLruCache.Editor editor = diskLruCache.edit(safeKey);
OutputStream os = editor.newOutputStream(0);
writer.write(os); // 写入数据(如 Bitmap 压缩后的字节流)
editor.commit();
}
}
实例分析
- 磁盘缓存文件结构:
- 缓存目录:
/data/data/com.example.app/cache/image_manager_disk_cache - 文件名:通过 URL、尺寸等参数生成的哈希值(如
a1b2c3d4.0)。
- 缓存目录:
总结:Glide 源码执行流程
- 初始化:
Glide.java配置全局参数,注册组件。 - 请求发起:
RequestManager.load(url)绑定生命周期。 - 缓存检查:
Engine检查活动缓存、内存缓存、磁盘缓存。 - 数据加载:未命中缓存时,
DecodeJob调度网络请求或文件读取。 - 解码与转码:
ResourceDecoder和Transcoder处理数据。 - 资源交付:通过
Target在主线程更新 UI。
通过分析关键源码文件,可以深入理解 Glide 的模块化设计、缓存策略和线程模型。调试时可结合日志(adb shell setprop log.tag.Glide VERBOSE)观察缓存命中与加载流程。
当前文章价值6.9元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

你可能感兴趣的文章
分类:glide
标签:DecodeJob, Engine, Glide, LruResourceCache, RequestManager
评论已关闭!