一句话总结:
用智能图书馆系统类比理解:
DiskLruCache就像一个自动管理的图书馆,它的运行规则是:
1. 每本书(数据)都有固定书架位置(磁盘文件)
2. 新书到馆优先放空书架
3. 书架满了淘汰最久没借阅的书(LRU规则)
4. 借阅记录实时更新(journal日志)
5. 书架损坏自动修复(数据一致性保障)
一、核心原理揭秘
1. 文件存储结构
缓存目录结构:
/app_cache
├── journal // 借阅记录本
├── 0a3b.data // 数据文件
├── 0a3b.tmp // 临时文件(写入中)
└── 1c2d.data // 另一本书
关键文件说明:
journal:记录所有操作(PUT/REMOVE/CLEAN等).data:正式缓存文件.tmp:写入时的临时文件(避免写入失败导致数据损坏)
2. LRU淘汰算法实现
// 源码核心逻辑(简化版)
fun trimToSize(maxSize: Long) {
while (currentSize > maxSize) {
val toEvict = lruEntries.values.iterator().next()
deleteEntry(toEvict) // 删除最久未使用的条目
}
}
淘汰流程:
- 遍历LinkedHashMap(按访问顺序排列)
- 从头部开始删除直到满足容量要求
- 更新journal日志
二、使用四步曲
1. 初始化图书馆
// 创建缓存(2025推荐使用SafeDiskLruCache)
val cache = SafeDiskLruCache.open(
directory = context.externalCacheDir, // 缓存目录
appVersion = 2, // 版本号(升级时自动清理旧缓存)
valueCount = 1, // 每个key对应文件数
maxSize = 1024 * 1024 * 100, // 100MB
secureKey = "your_quantum_key" // 加密密钥
)
2. 存书流程(写入数据)
// 异步写入(协程示例)
suspend fun saveImage(key: String, bitmap: Bitmap) = withContext(Dispatchers.IO) {
val editor = cache.edit(key) ?: return@withContext
try {
// 将Bitmap写入输出流
FileOutputStream(editor.newOutputStream(0)).use {
bitmap.compress(Bitmap.CompressFormat.WEBP_LOSSY, 80, it)
}
editor.commit() // 提交写入
} catch (e: Exception) {
editor.abort() // 回滚写入
}
}
3. 取书流程(读取数据)
// 同步读取
fun loadImage(key: String): Bitmap? {
val snapshot = cache.get(key) ?: return null
return BitmapFactory.decodeStream(snapshot.getInputStream(0))
}
// 异步带缓存的网络请求示例
fun loadImageWithCache(url: String) = flow {
val key = url.md5()
// 先查磁盘缓存
loadImage(key)?.let {
emit(it)
return@flow
}
// 缓存未命中则下载
val bitmap = downloadImage(url)
saveImage(key, bitmap)
emit(bitmap)
}
4. 清理维护
// 手动清理缓存
cache.delete() // 清空全部
cache.evictAll() // 按LRU规则清理
// 自动维护(2025新增API)
cache.setAutoMaintenance(
interval = 24, // 每24小时自动清理
policy = { entry ->
// 自定义清理策略:超过7天未访问
System.currentTimeMillis() - entry.lastAccessTime > 7 * 24 * 3600 * 1000
}
)
三、避坑指南
坑1:跨进程访问冲突
现象:多进程同时写入导致文件损坏
解决方案:
// 使用跨进程安全版本
val cache = CrossProcessDiskLruCache.open(
directory,
lockType = LockType.QUANTUM_MUTEX // 量子互斥锁
)
坑2:固态硬盘磨损均衡
错误用法:高频写入小文件导致SSD寿命下降
优化方案:
// 启用批量写入模式
cache.enableBatchWrite(
interval = 5, // 每5秒批量提交一次
maxBatchSize = 100
)
四、最佳实践
1. 三级缓存架构
[网络请求]
↓
[内存缓存 LruCache] ←→ [DiskLruCache]
↓
[SQLite数据库]
策略:
- 内存缓存作为第一级快速响应
- 磁盘缓存避免重复网络请求
- 数据库持久化重要数据
2. 智能预加载
// 根据用户行为预测加载
fun preloadData(user: User) {
val predictor = BehaviorPredictor(context)
predictor.getNextLikelyData { predictedKeys ->
predictedKeys.forEach { key ->
if (!cache.contains(key)) {
launch {
val data = fetchFromNetwork(key)
cache.put(key, data)
}
}
}
}
}
DiskLruCache终极口诀:
磁盘缓存选它强,文件管理有保障
journal日志记操作,数据一致不会慌
加密压缩功能全,2025特性更安全
多级缓存配合用,性能体验双提升
避坑注意多进程,预加载入更智能!