美文网首页
Glide原理

Glide原理

作者: 何先生与小花匠 | 来源:发表于2025-03-02 13:24 被阅读0次

1. 请求启动与构建流程(源码级解析)

    调用链:Glide.with(context).load(url).into(imageView)

(1) Glide.with(context) 初始化

    生命周期绑定:根据 context 类型(Activity/Fragment/Application)创建隐藏的 SupportRequestManagerFragment,通过 RequestManagerRetriever 获取 RequestManager

// RequestManagerRetriever.java
public RequestManager get(Context context) {
    if (context == null) return getApplicationManager(context);
    if (context instanceof Activity) {
        return get((Activity) context);
    } else if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
    }
    // ...其他类型处理
}

    作用:将图片加载请求与组件的生命周期(如 onStart, onStop)绑定,避免内存泄漏。

(2) load(url) 构建请求参数

    创建 RequestBuilder,设置数据模型(URL、URI、资源ID等)。

    关键类:RequestManager生成 RequestBuilder,通过泛型指定资源类型。

(3) into(imageView) 发起请求

    步骤分解:

    创建 Target:将 ImageView 包装为 ImageViewTarget(如 BitmapImageViewTarget)。

    构建 Request:通过 RequestBuilder生成 SingleRequest对象。

    执行请求:调用 Request.begin(),进入加载流程。

2. 多级缓存机制(深度解析)

(1) 活动缓存(ActiveResources

    实现类:ActiveResources

    数据结构:Map<Key, ResourceWeakReference>,使用弱引用(WeakReference)持有正在使用的资源。

    回收逻辑:通过 ReferenceQueue 监听弱引用回收,资源不再使用时移入内存缓存。

// ActiveResources.java
void cleanupActiveReference(@NonNull ResourceWeakReference ref) {
    EngineResource<?> removed = activeEngineResources.remove(ref.key);
    if (removed != null) {
        removed.setResourceListener(null);
        cache.put(removed); // 移入内存缓存
    }
}

(2) 内存缓存(MemoryCache)

    默认实现:LruResourceCache(基于LRU算法的LinkedHashMap)。

    缓存键(Key):由 EngineKey 生成,包含URL、尺寸、解码器、变换等参数。

// EngineKey.java
public boolean equals(Object o) {
    if (o instanceof EngineKey) {
        EngineKey other = (EngineKey) o;
        return model.equals(other.model) 
            && signature.equals(other.signature)
            && width == other.width 
            && height == other.height;
    }
    return false;
}

(3) 磁盘缓存(DiskCache)

    策略:分为 DATA(原始数据)和 RESOURCE(处理后的数据)。

    写入流程:通过 DiskLruCacheWrapper 实现,使用LRU算法管理文件。

// DiskLruCacheWrapper.java
public void put(Key key, Writer writer) {
    String safeKey = safeKeyGenerator.getSafeKey(key);
    diskLruCache.edit(safeKey).set(0, writer);
}

3. Bitmap 复用机制(BitmapPool)

(1) 实现原理

    核心类:LruBitmapPool

    数据结构:按 Bitmap 的尺寸和配置(ARGB_8888等)分组存储,使用 TreeMapHashMap 管理。

    复用逻辑:查找尺寸大于等于需求且配置匹配的 Bitmap,调用 reconfigure() 调整尺寸。

// LruBitmapPool.java
public synchronized Bitmap get(int width, int height, Bitmap.Config config) {
    Bitmap result = strategy.get(width, height, config);
    if (result == null) {
        result = createBitmap(width, height, config);
    }
    return result;
}

(2) 避免 GC 压力

    直接内存分配:通过 Bitmap.createBitmap()inBitmap 参数复用内存(需API 11+)。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inMutable = true;
options.inBitmap = reusableBitmap; // 复用内存
Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);

4. 解码与转码流程(详细步骤)

(1) 解码链(DecodePath)

    注册机制:Glide 通过 Registry 注册多个 ResourceDecoder

// Registry.java
public Registry add(Class<T> dataClass, Class<R> resourceClass, ResourceDecoder<T, R> decoder) {
    decoderRegistry.append(dataClass, resourceClass, decoder);
    return this;
}

    匹配流程:按优先级选择第一个可处理数据类型的 Decoder

(2) 转码(Transcode)

    作用:将解码后的资源转换为目标类型(如 Bitmap → Drawable)。

    核心接口:ResourceTranscoder<Z, R>

// BitmapDrawableTranscoder.java
public Resource<BitmapDrawable> transcode(Resource<Bitmap> toTranscode) {
    return new BitmapDrawableResource(new BitmapDrawable(context.getResources(), toTranscode.get()));
}

5. 线程池与并发模型(源码配置)

(1) 线程池类型与参数

线程池名称 核心线程数 队列类型 用途
sourceExecutor 核心数+1 PriorityBlockingQueue 加载原始数据(网络/文件)
diskCacheExecutor 1 FIFO队列 磁盘缓存读写
animationExecutor 2 LinkedBlockingQueue GIF 帧解码

(2) 任务调度逻辑

    磁盘缓存任务:由 diskCacheExecutor 单线程执行,避免并发读写冲突。

    网络请求:通过 sourceExecutor 执行,支持并发但限制最大线程数。

6. 生命周期管理(源码级实现)

(1) 隐式 Fragment 机制

    创建 Fragment:在 RequestManagerRetriever 中为 Activity 添加无UI的 Fragment

// RequestManagerRetriever.java
private SupportRequestManagerFragment getSupportRequestManagerFragment(
    final FragmentManager fm) {
    SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
        current = new SupportRequestManagerFragment();
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
    }
    return current;
}

(2) 生命周期回调

    绑定 RequestManager:Fragment 的生命周期事件传递给 RequestManager

// SupportRequestManagerFragment.java
@Override
public void onStart() {
    super.onStart();
    requestManager.onStart();
}

7. 自定义扩展(高级用法示例)

(1) 自定义 ModelLoader

    目标:加载自定义协议(如 asset://image.png)。

public class AssetModelLoader implements ModelLoader<String, InputStream> {
    @Override
    public LoadData<InputStream> buildLoadData(String model, int width, int height) {
        return new LoadData<>(new ObjectKey(model), new AssetDataFetcher(model));
    }
}

(2) 注册自定义组件

    通过 GlideModule:在 AppGlideModule 中注册。

@GlideModule
public class MyAppGlideModule extends AppGlideModule {
    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) {
        registry.append(String.class, InputStream.class, new AssetModelLoader.Factory());
    }
}

总结:Glide 的极致优化设计

    内存管理:通过三级缓存 + BitmapPool 减少内存分配和GC。

    线程模型:多线程池分工,确保主线程流畅。

    生命周期感知:自动管理请求生命周期,避免泄漏。

    高效解码:灵活的 Decoder/Transcoder 链支持多种数据源。

    高度可扩展:允许深度定制各组件(缓存、加载、解码等)。

    通过以上机制,Glide 在 性能 和 易用性 上达到平衡,成为 Android 图片加载的事实标准。

相关文章

  • Glide 图片加载连接超时

    参考文章 Glide 4.x添加自定义组件原理Glide 系列-1:预热、Glide 的常用配置方式及其原理Gli...

  • Glide 源码学习补漏,Glide 图片缓存原理探究

    基于 Gilde 4.3.1 上一篇Glide 源码学习,了解 Glide 图片加载原理中分析了 Glide 加载...

  • Glide源码解析(4.X版本)

    知识点汇总: 一:Glide项目概述 二:Glide加载图片的原理 三:Glide三级缓存的设计 四:Glide如...

  • Glide 缓存原理实现

    Glide 缓存原理实现 专注于Android开发,分享经验总结,欢迎加入QQ群:686809487 Glide缓...

  • Glide原理

  • glide原理

    首先先了解图片三级缓存: 三级缓存可以减少不必要的流量消耗,增加加载速度1,内存缓存,优先加载,速度最快2.本地缓...

  • 探究Glide的运行原理 (2)

    前言 上一篇探究Glide的运行原理(1))我们主要了解了一下Glide的简介以及简单的使用,同时也对Glide....

  • Android面试 Glide源码流程

    面试问题 简单介绍一下Glide缓存 具体说说Glide的三级缓存原理 Glide加载一个100x100的图片,是...

  • Glide框架初识

    Glide原理 Glide在加载绑定了Activity的生命周期。 在Activity内新建一个无UI的Fragm...

  • Glide如何自动管理生命周期

    Glide管理生命周期还是很有想法的,这种思路值得我们去学习和应用; 特点 实现原理 源码分析 Glide.wit...

网友评论

      本文标题:Glide原理

      本文链接:https://www.haomeiwen.com/subject/fdvipjtx.html