一、Glide缓存体系概览
Glide采用了三级缓存设计,构成了一个高效的图片加载缓存体系:
-
活动资源缓存 (Active Resources) - 内存中的第一级缓存
-
内存缓存 (Memory Cache) - 内存中的第二级缓存
-
磁盘缓存 (Disk Cache) - 持久化存储缓存
// Glide缓存初始化核心代码 GlideBuilder.build() { // 1. 活动资源缓存 setMemoryCache(new LruResourceCache(memoryCacheSize)); // 2. 内存缓存 setBitmapPool(new LruBitmapPool(bitmapPoolSize)); // 3. 磁盘缓存 setDiskCache(new InternalCacheDiskCacheFactory(context)); }
二、活动资源缓存 (Active Resources)
设计原理
-
使用弱引用存储正在使用的资源
-
采用
Map<Key, ResourceWeakReference>
结构 -
生命周期与Activity/Fragment绑定
// 活动资源缓存核心实现 public class ActiveResources { private final Map<Key, ResourceWeakReference> activeEngineResources = new HashMap<>(); void activate(Key key, EngineResource<?> resource) { ResourceWeakReference ref = new ResourceWeakReference(key, resource); activeEngineResources.put(key, ref); } }
特点
-
快速响应正在显示的图片请求
-
防止重复加载同一资源
-
当内存不足时会被优先回收
三、内存缓存 (Memory Cache)
LruCache实现
public class LruResourceCache extends LruCache<Key, Resource> {
// 默认大小为设备内存的1/8
public static final int DEFAULT_MEM_CACHE_SIZE = (int) (Runtime.getRuntime().maxMemory() / 8);
@Override
protected int getSize(Resource resource) {
return resource.getSize();
}
}
工作流程
-
检查活动资源缓存 → 2. 检查内存缓存 → 3. 检查磁盘缓存 → 4. 从网络/本地加载
四、磁盘缓存 (Disk Cache)
分层设计
-
原始数据缓存 (DATA_CACHE) - 存储原始图片数据
-
转换后缓存 (RESOURCE_CACHE) - 存储处理后的图片
// 磁盘缓存策略 public enum DiskCacheStrategy { ALL, // 存储原始和转换后数据 NONE, // 不缓存 DATA, // 只缓存原始数据 RESOURCE, // 只缓存转换后数据 AUTOMATIC // 智能选择 }
实现原理
public class DiskLruCacheWrapper implements DiskCache {
private final DiskLruCache diskLruCache;
@Override
public File get(Key key) {
String safeKey = safeKeyGenerator.getSafeKey(key);
return diskLruCache.get(safeKey);
}
}
五、Bitmap池设计 (Bitmap Pool)
核心作用
-
重用Bitmap内存,减少GC
-
基于LRU算法管理
public class LruBitmapPool implements BitmapPool { private final LruPoolStrategy strategy; private final Set<Bitmap> trackedBitmaps = Collections.synchronizedSet(new HashSet<>()); @Override public void put(Bitmap bitmap) { if (!bitmap.isMutable()) return; strategy.put(bitmap); } }
六、缓存键生成策略
Glide使用多维度的Key来唯一标识缓存项:
public class EngineKey implements Key {
private final Object model; // 图片URL/File等
private final int width; // 目标宽度
private final int height; // 目标高度
private final Options options; // 变换/解码选项
@Override
public boolean equals(Object o) {
// 所有字段参与比较
}
@Override
public int hashCode() {
// 所有字段参与计算
}
}
七、深度问题解析
Q1:Glide如何避免图片加载时的内存泄漏?
答:
-
使用Fragment生命周期管理请求
public class RequestManagerFragment extends Fragment { @Override public void onDestroy() { super.onDestroy(); requestManager.clear(); } }
-
活动资源缓存使用弱引用
-
提供手动清除缓存API:
Glide.get(context).clearMemory()
Q2:Glide与Picasso缓存机制的主要区别?
特性 | Glide | Picasso |
---|---|---|
内存缓存 | 活动资源+内存缓存+Bitmap池 | 仅LRU内存缓存 |
磁盘缓存 | 原始+转换后双缓存 | 仅原始数据缓存 |
Bitmap复用 | 支持 | 不支持 |
缓存键 | 多维度复杂Key | 简单URL Key |
Q3:如何自定义Glide的磁盘缓存?
Glide.init(GlideBuilder()
.setDiskCache(new DiskCache.Factory() {
@Override
public DiskCache build() {
return new DiskLruCacheWrapper(
new File(cacheDir, "glide_cache"),
MAX_CACHE_SIZE);
}
})
);
八、性能优化实践
-
合理设置缓存大小
// 自定义内存缓存大小 new GlideBuilder() .setMemoryCache(new LruResourceCache(customSize));
2.根据场景选择缓存策略
Glide.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL) // 根据需求调整
.into(imageView);
3.监控缓存命中率
// 添加监听器统计缓存效果
glideEngine.setMemoryCacheListener(new MemoryCacheListener() {
@Override
public void onResourceRemoved(Resource<?> removed) {
// 统计缓存移除情况
}
});
Glide的缓存设计充分考虑了Android平台特性和图片加载场景,通过多级缓存和智能回收机制,在内存占用和加载速度之间取得了良好平衡。理解其缓存机制有助于在实际开发中更好地使用和优化图片加载性能。