android Glide 源码流程分析

Android Glide 源码流程深度分析

Glide 4.x 的源码设计非常精巧,采用了分层架构 + 责任链 + 缓存分级的设计模式。下面从初始化到最终图片显示,逐层拆解其核心流程。


一、整体架构概览

Glide 的核心可以抽象为一条请求处理流水线

plain

复制代码
with() → load() → into()
   ↓       ↓        ↓
RequestManager → RequestBuilder → SingleRequest → Engine → DecodeJob → DataFetcher

核心类职责

类名 职责
Glide 单例入口,管理全局配置与组件注册
RequestManager 生命周期绑定,请求管理(暂停/恢复/取消)
RequestBuilder 构建请求参数(占位图、变换、缓存策略等)
SingleRequest 封装单次请求的状态机
Engine 核心调度器,负责缓存查询与任务分发
DecodeJob 后台解码任务,执行真正的数据加载与处理
DataFetcher 数据获取器(网络、文件、资源等)

二、初始化流程:Glide.get(context)

2.1 单例创建

java

复制代码
// Glide.java
public static Glide get(@NonNull Context context) {
    if (glide == null) {
        synchronized (Glide.class) {
            if (glide == null) {
                checkAndInitializeGlide(context);
            }
        }
    }
    return glide;
}

2.2 组件自动扫描

Glide 通过注解处理器(@GlideModule)在编译期生成 GlideGeneratedModule,初始化时通过反射或注解收集所有自定义配置:

java

复制代码
// 自动收集所有 @GlideModule 标注的类
GeneratedAppGlideModule generatedAppGlideModule = 
    annotationGeneratedModule != null ? annotationGeneratedModule.get() : null;

2.3 GlideBuilder 构建核心组件

java

复制代码
// GlideBuilder.java
Glide build(@NonNull Context context) {
    // 1. 线程池
    sourceExecutor = GlideExecutor.newSourceExecutor();
    diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    animationExecutor = GlideExecutor.newAnimationExecutor();
    
    // 2. 内存缓存(默认 LruResourceCache,大小为内存的 1/8)
    memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    
    // 3. 磁盘缓存(默认 InternalCacheDiskCacheFactory,250MB)
    diskCacheFactory = new InternalCacheDiskCacheFactory(context, 250 * 1024 * 1024);
    
    // 4. 构建 Engine
    engine = new Engine(memoryCache, diskCacheFactory, ...);
    
    // 5. 构建 RequestManagerRetriever(负责管理 RequestManager 与生命周期绑定)
    requestManagerRetriever = new RequestManagerRetriever(requestManagerFactory);
    
    return new Glide(context, engine, memoryCache, ...);
}

关键设计Registry 类维护了一个类型映射表 ,注册所有支持的 ModelLoaderEncoderResourceDecoderResourceTranscoder,这是 Glide 支持多数据源(URL、File、Uri、ResourceId)的核心机制。


三、请求构建链:with() → load() → into()

3.1 with():生命周期绑定

java

复制代码
// RequestManagerRetriever.java
public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
        return get(activity.getApplicationContext()); // 后台线程降级到 Application 级别
    } else {
        // 主线程:创建无 UI 的 Fragment 绑定生命周期
        return fragmentGet(activity, activity.getSupportFragmentManager(), null, isActivityVisible(activity));
    }
}

核心机制 :Glide 会创建一个 SupportRequestManagerFragment (或 RequestManagerFragment),这是一个没有视图的 Fragment,通过 FragmentManager 绑定到宿主 Activity/Fragment 上,监听 onStart()onStop()onDestroy() 事件。

java

复制代码
// SupportRequestManagerFragment.java
@Override
public void onStart() {
    super.onStart();
    requestManager.onStart(); // 恢复请求
}

@Override
public void onStop() {
    super.onStop();
    requestManager.onStop(); // 暂停请求
}

@Override
public void onDestroy() {
    super.onDestroy();
    requestManager.onDestroy(); // 取消并清理请求
}

3.2 load():构建 RequestBuilder

java

复制代码
// RequestManager.java
public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
}

public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class); // 指定返回类型
}

RequestBuilder 是一个泛型构建器,通过链式调用收集配置:

  • placeholder()error()fallback()

  • override()transform()transition()

  • diskCacheStrategy()priority()

3.3 into():启动请求引擎

java

复制代码
// RequestBuilder.java
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    // 1. 根据 ImageView 的 scaleType 确定变换策略
    BaseRequestOptions<?> requestOptions = this;
    if (!requestOptions.isTransformationSet() && requestOptions.isTransformationAllowed()) {
        switch (view.getScaleType()) {
            case CENTER_CROP: requestOptions = requestOptions.clone().optionalCenterCrop(); break;
            case FIT_CENTER: requestOptions = requestOptions.clone().optionalFitCenter(); break;
            // ...
        }
    }
    
    // 2. 构建 Target(通常是 ImageViewTarget)
    return into(context.buildImageViewTarget(view, transcodeClass), null, requestOptions);
}

最终调用:

java

复制代码
private <Y extends Target<TranscodeType>> Y into(
    @NonNull Y target, 
    @Nullable RequestListener<TranscodeType> listener, 
    BaseRequestOptions<?> options) {
    
    // 3. 构建 SingleRequest
    Request request = buildRequest(target, targetListener, options, coordinator);
    
    // 4. 设置请求到 Target
    target.setRequest(request);
    
    // 5. 提交请求
    requestManager.track(target, request);
    
    return target;
}

四、Engine 核心调度:缓存查询与任务分发

RequestManager.track() 最终调用 SingleRequest.begin(),进而触发 Engine.load(),这是整个加载流程的中央枢纽

4.1 Engine.load() 入口

java

复制代码
// Engine.java
public <R> LoadStatus load(
    GlideContext glideContext,
    Object model, // 原始数据(如 URL String)
    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) {
    
    // 1. 构建缓存 Key(基于模型、尺寸、签名、变换等)
    EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
        resourceClass, transcodeClass, options);
    
    // 2. 从 ActiveResources 查询(正在使用的资源,弱引用缓存)
    EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
    if (active != null) {
        cb.onResourceReady(active, DataSource.MEMORY_CACHE);
        return new LoadStatus(cb, active);
    }
    
    // 3. 从 LruResourceCache 查询(内存缓存)
    EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
    if (cached != null) {
        cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
        return new LoadStatus(cb, cached);
    }
    
    // 4. 检查是否有正在进行的相同请求(避免重复加载)
    EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
    if (current != null) {
        current.addCallback(cb);
        return new LoadStatus(cb, current);
    }
    
    // 5. 缓存未命中,启动新任务
    EngineJob<R> engineJob = engineJobFactory.build(...);
    DecodeJob<R> decodeJob = decodeJobFactory.build(...);
    
    jobs.put(key, engineJob);
    engineJob.addCallback(cb);
    engineJob.start(decodeJob);
    
    return new LoadStatus(cb, engineJob);
}

4.2 三级缓存体系

plain

复制代码
┌─────────────────────────────────────────────────────────┐
│                    Engine.load()                         │
├─────────────────────────────────────────────────────────┤
│  1. ActiveResources (弱引用)                             │
│     → 正在显示的图片,命中直接回调                        │
├─────────────────────────────────────────────────────────┤
│  2. LruResourceCache (LRU 内存缓存)                      │
│     → 最近使用过的图片,命中后提升到 ActiveResources      │
├─────────────────────────────────────────────────────────┤
│  3. DiskLruCache (磁盘缓存)                              │
│     → 持久化存储,通过 DecodeJob 在后台线程读取           │
└─────────────────────────────────────────────────────────┘

ActiveResources 设计精妙之处

java

复制代码
// ActiveResources.java
final Map<Key, ResourceWeakReference> activeEngineResources = new HashMap<>();

// 使用弱引用 + ReferenceQueue,当资源不再被 View 持有时自动清理
private static final class ResourceWeakReference extends WeakReference<EngineResource<?>> {
    final Key key;
    
    ResourceWeakReference(Key key, EngineResource<?> referent, ReferenceQueue<? super EngineResource<?>> queue) {
        super(referent, queue);
        this.key = key;
    }
}

当 Activity 销毁时,View 被释放,弱引用被回收,资源从 ActiveResources 移除,若其他地方未引用则进入 LruResourceCache 或直接被回收。


五、DecodeJob:后台解码执行器

DecodeJob 实现了 Runnable,被提交到 GlideExecutor 线程池执行,是真正的数据加载与处理单元

5.1 执行阶段模型(FetcherStage)

DecodeJob 采用阶段推进模式,按优先级依次尝试:

java

复制代码
// DecodeJob.java
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;
    }
}

private Stage getNextStage(Stage current) {
    switch (current) {
        case INITIALIZE:
            return diskCacheStrategy.decodeCachedResource() ? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
        case RESOURCE_CACHE:
            return diskCacheStrategy.decodeCachedData() ? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
        case DATA_CACHE:
            return Stage.SOURCE; // 最终从原始源加载
        case SOURCE:
        case FINISHED:
            return Stage.FINISHED;
    }
}

三个阶段

表格

阶段 说明 对应 Generator
RESOURCE_CACHE 读取磁盘缓存中的转换后图片(如裁剪后的图片) ResourceCacheGenerator
DATA_CACHE 读取磁盘缓存中的原始数据(如原始下载文件) DataCacheGenerator
SOURCE 从原始源加载(网络、本地文件等) SourceGenerator

5.2 SourceGenerator 数据加载流程

java

复制代码
// SourceGenerator.java
public boolean startNext() {
    // 1. 通过 ModelLoader 构建 DataFetcher
    loadData = helper.getLoadData().get(loadDataListIndex++);
    fetcher = loadData.fetcher;
    
    // 2. 执行数据获取(网络请求或文件读取)
    fetcher.loadData(helper.getPriority(), this);
    return true;
}

ModelLoader 匹配机制

Glide 的 Registry 维护了 Model -> Data -> Resource -> Transcoded 的完整链条。以加载网络图片为例:

plain

复制代码
String (URL) 
    ↓ [ModelLoader: HttpUriLoader / StringLoader]
InputStream / ByteBuffer
    ↓ [Decoder: StreamBitmapDecoder / ByteBufferBitmapDecoder]
Bitmap
    ↓ [Transformation: CenterCrop / FitCenter]
Bitmap (Transformed)
    ↓ [Transcoder: BitmapDrawableTranscoder]
BitmapDrawable / Drawable
    ↓ [Target: ImageViewTarget]
ImageView

5.3 解码与变换

数据获取成功后,进入 DecodeJob.onDataFetcherReady()

java

复制代码
private void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher, DataSource dataSource) {
    // 1. 解码
    Resource<R> decoded = decodeFromData(dataFetcher, data, dataSource);
    
    // 2. 变换(如 centerCrop、圆角等)
    Resource<R> transformed = encodeAndTransform(decoded, dataSource);
    
    // 3. 回调到 Engine
    notifyEncodeAndRelease(transformed, currentSourceKey, dataSource);
}

磁盘缓存写入

java

复制代码
private void encodeAndTransform(Resource<R> resource, DataSource dataSource) {
    // 写入转换后的资源缓存(RESOURCE_CACHE)
    if (diskCacheStrategy.cacheResource()) {
        diskCacheProvider.getDiskCache().put(key, new ResourceEncoder<>(resource, encoder));
    }
    
    // 写入原始数据缓存(DATA_CACHE)
    if (diskCacheStrategy.cacheData() && dataSource != DataSource.DATA_DISK_CACHE && dataSource != DataSource.RESOURCE_DISK_CACHE) {
        diskCacheProvider.getDiskCache().put(originalKey, new DataCacheWriter<>(encoder, data));
    }
}

六、缓存机制深度解析

6.1 内存缓存:ActiveResources + LruResourceCache

java

复制代码
// LruResourceCache.java(继承 LruCache)
@Override
protected int getSize(@Nullable Bitmap bitmap) {
    return Util.getBitmapByteSize(bitmap); // 精确计算 Bitmap 内存占用
}

@Override
protected void onItemEvicted(@NonNull Key key, @Nullable Resource<?> item) {
    // 当 LRU 淘汰时,回调到 Engine 进行清理
    listener.onResourceRemoved(key, item);
}

缓存提升流程

plain

复制代码
LruResourceCache (命中)
    ↓
EngineResource (引用计数+1)
    ↓
ActiveResources (弱引用持有)
    ↓
ImageView 显示
    ↓
ImageView 销毁 → 弱引用回收 → 引用计数-1 → 若计数为0,回收到 LruResourceCache 或释放

6.2 磁盘缓存:DiskLruCacheWrapper

Glide 使用 Jake Wharton 的 DiskLruCache 算法:

  • Key 生成 :基于 ObjectKey(URL + 签名 + 尺寸 + 变换参数),使用 SHA-256 哈希

  • 双缓存区

    • 原始数据缓存(DATA):保存下载的原始文件

    • 转换后资源缓存(RESOURCE):保存解码并变换后的 Bitmap,下次直接加载更快

java

复制代码
// DiskLruCacheWrapper.java
public void put(Key key, DiskCache.Writer writer) {
    String safeKey = safeKeyGenerator.getSafeKey(key); // SHA-256 哈希
    DiskLruCache.Editor editor = diskLruCache.edit(safeKey);
    writer.write(editor.getFile(0)); // 写入临时文件
    editor.commit(); // 提交
}

七、生命周期管理原理

Glide 的生命周期管理是其避免内存泄漏的核心设计。

7.1 Fragment 绑定机制

java

复制代码
// RequestManagerRetriever.java
private RequestManagerFragment getRequestManagerFragment(
    @NonNull final android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint,
    boolean isParentVisible) {
    
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
        current = pendingRequestManagerFragments.get(fm);
        if (current == null) {
            current = new RequestManagerFragment();
            current.setParentFragmentHint(parentHint);
            pendingRequestManagerFragments.put(fm, current);
            
            // 提交 Fragment 事务
            fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
            handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
        }
    }
    return current;
}

关键点

  • 使用 commitAllowingStateLoss() 避免状态丢失崩溃

  • 通过 Handler 延迟清理 pendingRequestManagerFragments,避免重复创建

7.2 请求状态机

java

复制代码
// SingleRequest.java
enum Status {
    PENDING,    // 等待中
    RUNNING,    // 执行中
    WAITING_FOR_SIZE, // 等待尺寸确定(ImageView 布局完成后)
    COMPLETE,   // 完成
    FAILED,     // 失败
    CANCELLED,  // 取消
    CLEARED,    // 清理
    PAUSED      // 暂停
}

当 Activity onStop() 时,所有关联的 Request 进入 PAUSED 状态,Glide 暂停数据加载和动画播放;onStart() 时恢复;onDestroy() 时进入 CLEARED,释放所有资源引用。


八、线程模型

Glide 使用多线程池分工协作:

表格

线程池 用途 线程数
sourceUnlimitedExecutor 无限制网络请求(大图/长图) 无限制
sourceExecutor 常规数据加载(网络、文件解码) CPU 核心数
diskCacheExecutor 磁盘缓存读写 1-4 线程
animationExecutor GIF 动画帧解码 1 线程

线程切换

java

复制代码
// EngineJob.java
private void notifyCallbacksOfResult() {
    // 回调到主线程更新 UI
    handler.obtainMessage(MSG_COMPLETE, this).sendToTarget();
}

// 主线程 Handler
private static final Handler CALLBACK_EXECUTOR = new Handler(Looper.getMainLooper(), new MainThreadCallback());

所有耗时操作(网络请求、文件 IO、Bitmap 解码)都在后台线程完成,最终通过 Handler 切换到主线程回调 onResourceReady() 更新 ImageView。


九、关键设计模式总结

模式 应用
Builder 模式 GlideBuilderRequestBuilder 链式配置
工厂模式 ModelLoaderFactoryDataFetcher 创建
责任链模式 DecodeJobStage 推进(RESOURCE_CACHE → DATA_CACHE → SOURCE)
享元模式 EngineResource 引用计数复用
观察者模式 RequestListenerTarget 回调机制
代理模式 EngineJob 代理 DecodeJob,管理多个回调

十、流程总图

plain

复制代码
用户调用
    │
    ▼
Glide.with(activity) ──→ 创建/获取 RequestManager ──→ 绑定 SupportRequestManagerFragment
    │
    ▼
.load(url) ──→ 返回 RequestBuilder<Drawable>(收集配置参数)
    │
    ▼
.into(imageView) ──→ 构建 SingleRequest ──→ RequestManager.track()
    │
    ▼
Engine.load()
    │
    ├──→ ActiveResources.get(key) ──→ 命中?──→ 直接回调
    │
    ├──→ LruResourceCache.get(key) ──→ 命中?──→ 提升到 ActiveResources ──→ 回调
    │
    └──→ 未命中 ──→ 创建 EngineJob + DecodeJob ──→ 提交线程池
            │
            ▼
    DecodeJob.run() ──→ 阶段推进
            │
            ├──→ Stage.RESOURCE_CACHE ──→ 读取磁盘转换缓存
            ├──→ Stage.DATA_CACHE ──→ 读取磁盘原始缓存
            └──→ Stage.SOURCE ──→ SourceGenerator.startNext()
                    │
                    ▼
            ModelLoader.buildLoadData() ──→ DataFetcher.loadData()
                    │
                    ▼
            网络请求/文件读取 ──→ 获取 InputStream
                    │
                    ▼
            ResourceDecoder.decode() ──→ Bitmap
                    │
                    ▼
            Transformation.transform() ──→ 变换后 Bitmap
                    │
                    ▼
            ResourceTranscoder.transcode() ──→ Drawable
                    │
                    ▼
            写入磁盘缓存(若配置)──→ 回调 EngineJob
                    │
                    ▼
            Handler ──→ 主线程 ──→ Target.onResourceReady() ──→ ImageView.setImageDrawable()

Glide 源码的精髓在于高度的模块化与可扩展性 :通过 Registry 注册机制支持任意数据源,通过 Engine 的三级缓存实现极致性能,通过 无 UI Fragment 实现生命周期自动感知,同时保持 API 的简洁性。理解这套流程,对设计高性能图片加载组件或优化 App 内存都有重要参考价值。

相关推荐
Android-Flutter1 小时前
android Glide 使用详解
android·kotlin
恋猫de小郭2 小时前
Dart 3.13 的到底改了什么?为什么很重要?有什么坑?
android·前端·flutter
HZZD_HZZD2 小时前
3T-UEM 数据建模实战:三维立方体 + LAM/ELA 双归因怎么落地?
android
Carson带你学Android2 小时前
腾讯正式上线AI应用生成平台:一句话生成 App,还能直接上架商店
android·ai编程
小陈的进阶之路3 小时前
Claude Code辅助测试:API测试与pytest自动化
android·开发语言·kotlin
三少爷的鞋3 小时前
Kotlin 与 Java,不是简单的高低之分
android
一笑的小酒馆9 小时前
Android12Launcher3实现应用裁剪
android
FinelyYang15 小时前
UniApp + LiveKit:Android 端为什么要用原生做屏幕共享,以及我们怎么落地的
android·uni-app
蓝速科技15 小时前
蓝速科技信创落地:平衡安全合规与项目成本的实战方案
android·运维·人工智能·科技·安全·电脑·鸿蒙