跳到主要内容

Glide 核心原理

问题

Glide 的三级缓存和生命周期绑定是如何实现的?

答案

Glide 架构

三级缓存

层级类型实现说明
L1Active ResourcesWeakReference HashMap正在显示的图片
L2Memory CacheLruCache未显示但常用的图片
L3Disk CacheDiskLruCache原始图片 + 转换后的图片

Active Resources 的设计:正在被 View 引用的图片用弱引用持有,不占用 LruCache 配额。当 View 不再引用时,图片从 Active 移入 LruCache。

生命周期绑定

Glide 向 Activity/Fragment 添加一个不可见的 FragmentRequestManagerFragment),通过它监听宿主的生命周期,在 onStop 暂停加载、onDestroy 取消加载并清理资源。

常用配置

Glide.with(context)
.load(url)
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.transform(CenterCrop(), RoundedCorners(16))
.override(300, 300) // 指定加载尺寸,减少内存
.into(imageView)

自定义 AppGlideModule

@GlideModule
class MyGlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
// 自定义内存缓存大小
builder.setMemoryCache(LruResourceCache(20 * 1024 * 1024)) // 20MB
// 自定义磁盘缓存
builder.setDiskCache(InternalCacheDiskCacheFactory(context, 100 * 1024 * 1024))
}

override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
// 替换网络层为 OkHttp
registry.replace(GlideUrl::class.java, InputStream::class.java,
OkHttpUrlLoader.Factory())
}
}

常见面试问题

Q1: Glide 内存缓存的 key 是什么?

答案

Glide 的缓存 key 由多个要素组成:URL、宽高、变换(Transform)、签名(Signature)等。这意味着同一张图片不同尺寸会缓存多份。通过 override() 统一尺寸可以提高缓存命中率。

Q2: DiskCacheStrategy 各选项的区别?

答案

策略缓存原图缓存转换后说明
NONE不缓存
DATA只缓存原始数据
RESOURCE只缓存转换后
ALL都缓存
AUTOMATIC根据策略决定根据策略决定默认,智能判断

Q3: Glide 如何避免图片错位?

答案

每次调用 into(imageView) 时,Glide 会为该 ImageView 生成一个 Target。如果 ImageView 被复用(如 RecyclerView),新的 into() 调用会先取消之前 Target 的请求,再发起新请求。通过 View.setTag() 绑定当前请求,确保图片加载完成时只有最新请求的结果会被设置到 ImageView 上。

相关链接