图片加载库的缓存机制核心是 “空间换时间”,通过在内存和磁盘中缓存已加载的图片,避免重复从网络下载或本地读取,从而提升加载速度、减少网络流量和功耗。以下是其详细工作原理:
主流图片加载库(如 Glide、Picasso、Coil)均采用 “内存缓存 → 磁盘缓存 → 网络 / 本地源” 的三级缓存策略,优先级依次递减:
当请求加载图片时:
1. 先查「内存缓存」→ 命中则直接返回图片
2. 内存未命中 → 查「磁盘缓存」→ 命中则加载磁盘图片,同时写入内存缓存
3. 磁盘未命中 → 从「网络/本地文件」加载,加载成功后写入磁盘+内存缓存
作用:存储最近使用的图片,供应用快速访问(内存读写速度远快于磁盘 / 网络)。
存储介质:应用进程的内存(如 JVM 堆内存)。
核心原理:
缓存键(Key):通常是图片的唯一标识,如: 网络图片:URL 的 MD5 哈希值(避免 URL 特殊字符问题);本地图片:本地路径的哈希值或 URI;资源图片:资源 ID(如
R.drawable.icon)。
缓存值(Value):图片的内存表示,如:
原始图片数据(
byte[]);解码后的 bitmap(Android 中常用
Bitmap,需注意内存管理);封装后的图片对象(如 Glide 的
Resource<Bitmap>,包含 bitmap 和生命周期管理)。
淘汰策略:由于内存有限,需通过淘汰策略清理不常用图片,避免 OOM:
LRU(Least Recently Used):最常用,淘汰 “最近最少使用” 的图片(如 Glide 默认使用
LruCache);LFU(Least Frequently Used):淘汰 “使用频率最低” 的图片;FIFO(First In First Out):淘汰 “最早加入” 的图片。
内存限制:缓存大小通常限制为应用可用内存的一定比例(如 Glide 默认限制为设备总内存的 1/8),避免占用过多内存导致应用崩溃。
特点:
优点:速度最快(毫秒级访问);缺点:容量有限,应用进程销毁后缓存失效(如应用重启、进程被回收)。作用:持久化存储图片,弥补内存缓存的容量和生命周期限制。
存储介质:设备磁盘(如应用私有目录、SD 卡)。
核心原理:
存储路径:通常在应用的私有缓存目录(如 Android 的
/data/data/<包名>/cache/image_cache),避免被系统或用户误删。缓存内容:
原始图片文件(如从网络下载的
*.jpg/
*.png,未解码,体积小);可选:解码后的图片(如
Bitmap序列化存储,较少用,因序列化耗时)。
缓存键:与内存缓存一致(如 URL 的 MD5 哈希值),确保内存和磁盘缓存的一致性。淘汰策略:
LRU:同样使用 LRU 淘汰旧文件(如 Glide 的
DiskLruCache);大小限制:设置磁盘缓存总容量(如 50MB),超过则删除最旧文件;时间限制:可选设置文件过期时间(如 7 天未使用则删除)。
写入时机:图片从网络 / 本地源加载成功后,先写入磁盘,再解码写入内存。读取时机:内存未命中时,从磁盘读取图片,解码后写入内存,再返回给应用。
特点:
优点:容量大(可达几十 MB/GB),持久化存储(应用重启后仍可用);缺点:速度较慢(磁盘 IO 比内存慢 100 倍以上),需解码后才能使用。
OkHttp作为网络请求库),下载过程中可能包含:
进度监听;重试机制(网络异常时);缓存控制(如通过 HTTP 的
Cache-Control/
ETag判断是否需要重新下载)。
本地图片:从设备磁盘(如 SD 卡、应用资源目录)读取图片文件。
后续操作:加载成功后,将图片写入磁盘缓存(原始文件)和内存缓存(解码后的 bitmap),供下次使用。
Glide.get(context).clearDiskCache());图片更新(如服务器图片 URL 不变但内容更新,需手动移除对应缓存)。
被动失效:
内存缓存因淘汰策略被清理(如 LRU 淘汰旧图片);磁盘缓存因容量 / 时间限制被淘汰;应用进程被销毁(内存缓存失效);缓存文件损坏(如磁盘错误、文件被删除)。
不同库的缓存实现细节略有不同,核心逻辑一致:
| 特性 | Glide | Picasso | Coil(Kotlin) |
|---|---|---|---|
| 内存缓存 | LRU + 弱引用(避免 OOM) | LRU(默认) | LRU + 弱引用 |
| 磁盘缓存 | DiskLruCache(支持大小 / 时间限制) | DiskLruCache(仅支持大小限制) | DiskLruCache(支持大小 / 时间限制) |
| 缓存键生成 | URL MD5 + 签名(如尺寸 / 格式) | URL MD5 | URL MD5 + 配置(如尺寸 / 格式) |
| 图片解码优化 | 支持多种尺寸 / 格式,自动适配 | 需手动指定尺寸 | 自动适配尺寸,支持 WebP 等格式 |
avatar.jpg?v=2)或禁用缓存;对临时图片(如验证码),直接禁用磁盘缓存(仅内存缓存,进程销毁后失效)。
手动清理缓存:
提供 “清理缓存” 功能(如应用设置页),调用库的 API 清理内存 + 磁盘缓存;定期清理过期缓存(如启动时检查磁盘缓存的过期文件)。
优化图片加载配置:
按需加载图片尺寸(如
override(100, 100)),避免缓存过大尺寸的图片;使用合适的图片格式(如 WebP,体积比 JPG 小 30%),减少缓存占用。
三级缓存的核心价值是 “空间换时间”,适合数据重复访问率高、对加载速度敏感、网络环境不稳定的场景(如图片加载、列表数据缓存)。实际使用时,需通过合理配置缓存大小、过期策略、缓存键规则,平衡其优点与局限性,避免因配置不当导致的性能问题或数据不一致。
图片加载库的缓存原理可概括为 “三级缓存 + LRU 淘汰 + 唯一键标识”:
内存缓存负责 “快速响应”,磁盘缓存负责 “持久化与扩容”,网络 / 本地源负责 “原始获取”;通过合理的缓存策略,在速度、容量、一致性之间达到平衡,最终提升应用的图片加载体验。