glide缓存策略和缓存命中

一 缓存策略

1 Glide 的 diskCacheStrategy() 一共有 5 种枚举值(DiskCacheStrategy),每种的作用和区别如下:


1. DiskCacheStrategy.ALL

  • 作用:同时缓存原始图片(原图数据)和经过变换(比如裁剪、缩放)后的图片。

  • 特点:

    • 加载相同 URL 但不同尺寸的图片时会用到原图缓存重新生成,节省网络请求。
    • 占用磁盘空间较大。
  • 使用场景:同一图片需要加载多种尺寸版本时(比如列表缩略图 + 详情页原图)。

  • 示例:

    Glide.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .into(imageView)


2. DiskCacheStrategy.DATA

  • 作用:只缓存原始数据(网络下载的原图文件),不缓存经过变换后的版本。

  • 特点:

    • 如果相同 URL 但不同尺寸的图片会再次加载,需要重新执行变换(裁剪、缩放)。
    • 节省磁盘,但 CPU 会多次参与图片处理。
  • 使用场景:图片需要多次处理或每次显示尺寸不固定,且不介意重新计算。

  • 示例:

    Glide.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.DATA)
    .into(imageView)


3. DiskCacheStrategy.RESOURCE

  • 作用:只缓存经过变换处理后的图片,不缓存原始数据。

  • 特点:

    • 每次加载相同尺寸的图片时速度很快。
    • 如果需要加载不同尺寸的图片,就得重新从网络获取。
  • 使用场景:固定尺寸、固定变换的图片(比如头像 100×100)。

  • 示例:

    Glide.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
    .into(imageView)


4. DiskCacheStrategy.NONE

  • 作用:不缓存任何内容(既不缓存原图,也不缓存变换结果)。

  • 特点:

    • 每次都从源头重新加载(网络、本地、ContentProvider 等)。
    • 网络耗时高,但适合加载经常变化的图片(例如验证码、实时数据图)。
  • 使用场景:动态变化的图片。

  • 示例:

    Glide.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.NONE)
    .into(imageView)


5. DiskCacheStrategy.AUTOMATIC(默认值)

  • 作用:根据图片来源和变换自动选择最佳策略。

  • 特点:

    • 网络图片:一般缓存变换后的结果(类似 RESOURCE)。
    • 本地图片(assets、file):可能不缓存(因为本地读速度快)。
    • 大部分情况性能和空间占用平衡。
  • 使用场景:不想自己纠结用哪种策略时,直接用默认。

  • 示例:

    Glide.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC) // 可省略
    .into(imageView)


常用选择建议

  • 列表/固定尺寸头像等 → RESOURCE(加载快,占空间少)。
  • 同一图片多种尺寸 → ALL(减少网络请求)。
  • 动态图片(验证码/频繁变化) → NONE。
  • 懒得选 → 用默认 AUTOMATIC(Glide 4.x 优化得不错)。

如果在做车机空调App那种大图(2500px 宽背景),

会建议用 DiskCacheStrategy.RESOURCE 来直接缓存裁剪/缩放后的版本,

这样 Fragment 切换时就能秒加载,不会卡顿或闪烁。


2 Glide 缓存策略对比表


Glide diskCacheStrategy() 对比表

策略 是否缓存原图(DATA) 是否缓存变换后(RESOURCE) 优点 缺点 适用场景
ALL 原图 & 各种尺寸都可复用,减少网络请求 占磁盘最多 同一 URL 需要多种尺寸或变换
DATA 原图可复用,多尺寸可重新生成 每次都要重新变换,CPU 占用高 多尺寸、多变换,但磁盘紧张
RESOURCE 固定尺寸加载快,占磁盘少 换尺寸需要重新下载 固定尺寸图片(头像、列表)
NONE 每次都拉取最新 网络 & CPU 占用高 验证码、实时图片
AUTOMATIC(默认) 自动决定 自动决定 性能和空间平衡 不可控(依赖 Glide 判断) 大部分情况直接用它


车机空调大图场景建议

  • 如果背景图尺寸固定 → RESOURCE

    • 直接缓存最终展示尺寸,Fragment 切换秒加载。
  • 如果一个图多种尺寸(比如背景 + 缩略图) → ALL

    • 原图 + 各种变换都能直接复用,避免重复请求和变换。

记忆口诀

  • ALL:全缓存(原图 + 变换)
  • DATA:只原图(省空间但要重算)
  • RESOURCE:只结果(快但不通用)
  • NONE:啥都不留(实时变化)
  • AUTO:交给 Glide(偷懒模式)


二 检查缓存是否命中

Glide 缓存命中检查方案:

  • 日志配置
  • 不同缓存命中标识
  • 手动检查缓存 API(日志不够用时)

1. 开启 Glide 全量调试日志

复制代码
class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        Glide.init(
            this,
            GlideBuilder()
                .setLogLevel(Log.DEBUG) // 输出 DEBUG 级别日志
        )
    }
}

这样 Glide 会在 Logcat 中输出类似:

  • 内存缓存命中

    Loaded resource from MEMORY_CACHE

  • 磁盘缓存命中

    Loaded resource from DISK_CACHE

  • 网络/本地原始加载(没命中任何缓存)

    Loaded resource from DATA

说明:

  • MEMORY_CACHE → 命中内存缓存(速度最快,不走磁盘 IO)
  • DISK_CACHE → 命中磁盘缓存(会解码成 Bitmap)
  • DATA → 没有缓存,直接从网络、本地文件或 ContentProvider 读取

2. 通过 RequestListener 精准判断

有时不想看 Logcat,而是想在代码里记录命中情况,这可以用 RequestListener 判断 DataSource:

复制代码
Glide.with(context)
    .load(url)
    .listener(object : RequestListener<Drawable> {
        override fun onLoadFailed(
            e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean
        ): Boolean {
            Log.e("GlideCheck", "加载失败: ${e?.message}")
            return false
        }

        override fun onResourceReady(
            resource: Drawable?, model: Any?, target: Target<Drawable>?,
            dataSource: DataSource?, isFirstResource: Boolean
        ): Boolean {
            when (dataSource) {
                DataSource.MEMORY_CACHE -> Log.d("GlideCheck", "内存缓存命中")
                DataSource.DISK_CACHE -> Log.d("GlideCheck", "磁盘缓存命中")
                DataSource.DATA -> Log.d("GlideCheck", "缓存未命中(原始数据加载)")
                DataSource.REMOTE -> Log.d("GlideCheck", "网络加载")
                DataSource.LOCAL -> Log.d("GlideCheck", "本地文件加载")
                else -> Log.d("GlideCheck", "未知数据源")
            }
            return false
        }
    })
    .into(imageView)

这样不看日志也能准确知道缓存命中情况,并且可以在 UI 或调试工具里显示。


3. 手动检查缓存是否存在(不触发加载)

有时想提前判断某个 URL 是否已经在磁盘缓存里,可以用:

复制代码
fun isImageInCache(context: Context, url: String): Boolean {
    val future = Glide.with(context)
        .downloadOnly()
        .load(url)
        .onlyRetrieveFromCache(true) // 只从缓存取,不走网络
        .submit()

    return try {
        future.get() // 如果能拿到文件,说明有缓存
        true
    } catch (e: Exception) {
        false
    }
}

4. 实战判断逻辑

综合起来,可以这样判断:

  1. 先用 onlyRetrieveFromCache(true) 提前检测是否有磁盘缓存(可做预加载优化判断)。
  2. 加载时用 RequestListener 获取真实加载来源(内存/磁盘/网络)。
  3. 配合 Glide 日志 双重验证。

三 Glide缓存流程图

四 总结

  1. 缓存策略有五种:ALL,DATA,RESOURCE,NONE,AUTOMATIC(默认),即原图缓存、转换后缓存,原图缓存,转换后缓存,不缓存,由glide处理缓存策略。
  2. 缓存命中,可以通过日志查看,RequestListener 和onlyRetrieveFromCache(true) 来查看是否命中了缓存
相关推荐
安卓开发者38 分钟前
Android模块化架构深度解析:从设计到实践
android·架构
雨白1 小时前
HTTP协议详解(二):深入理解Header与Body
android·http
阿豪元代码1 小时前
深入理解 SurfaceFlinger —— 如何调试 SurfaceFlinger
android
阿豪元代码2 小时前
深入理解 SurfaceFlinger —— 概述
android
CV资深专家3 小时前
Launcher3启动
android
Code季风3 小时前
如果缓存和数据库更新失败,如何实现最终一致性?
数据库·分布式·缓存·微服务·性能优化
雅雅姐4 小时前
Android 16 的用户和用户组定义
android
没有了遇见4 小时前
Android ConstraintLayout 之ConstraintSet
android
余辉zmh5 小时前
【MySQL基础篇】:MySQL索引——提升数据库查询性能的关键
android·数据库·mysql