Retrofit与OkHttp缓存基础

本章聚焦 OkHttp 缓存模块的核心组件与运行机制,彻底理解 Cache、CacheStrategy 以及缓存目录/大小配置,才能在后续章节实现精确的动态缓存策略。

OkHttp 缓存架构概述

OkHttp 的缓存层位于应用层与网络层之间,由 CacheInterceptor 统一处理。一次请求进入后的执行顺序:

  1. 应用发起请求 → OkHttpClient
  2. 经过拦截器链,到达 CacheInterceptor
  3. CacheInterceptor 利用 CacheStrategy 判断是否使用缓存
  4. 若缓存命中且有效,直接返回缓存响应;否则请求网络
  5. 网络响应返回后更新缓存
关键认知: Retrofit 本身不管理缓存,所有缓存行为全部委托给底层 OkHttp 的 Cache 组件。因此掌握 OkHttp 缓存是动态缓存策略的根基。

Cache 类与 CacheStrategy

组件职责关键方法/属性
Cache管理磁盘存储,提供缓存的增删改查put()、get()、remove()、maxSize()、writeSuccessCount
CacheStrategy根据缓存头与请求头决策是否使用缓存get() 静态方法,返回 CacheStrategy 对象
CacheStrategy.Factory解析请求与缓存响应,生成策略对象内部维护 request、response、sentRequestMillis、receivedResponseMillis
CacheStrategy 决策规则: 根据 HTTP 缓存头(如 Cache-Control、Expires、ETag)计算缓存的有效性,并返回是否使用网络、是否使用缓存、或返回 504 网关超时。

缓存目录与大小配置

创建 Cache 对象需要指定磁盘目录和最大字节数。目录必须可写,否则 OkHttp 会静默降级(不缓存)。

// Java 示例
File cacheDir = new File(context.getCacheDir(), "http_cache");
int cacheSize = 10 * 1024 * 1024; // 10MB
Cache cache = new Cache(cacheDir, cacheSize);

OkHttpClient client = new OkHttpClient.Builder()
        .cache(cache)
        .build();
// Kotlin 示例
val cacheDir = File(context.cacheDir, "http_cache")
val cacheSize = 10L * 1024 * 1024
val cache = Cache(cacheDir, cacheSize)

val client = OkHttpClient.Builder()
    .cache(cache)
    .build()
常见错误: 目录路径使用 getExternalCacheDir() 时,若外部存储不可用,Cache 构造不会报错但缓存失效。建议统一使用 getCacheDir()。另外 maxSize 单位是字节,建议用 int 或 long 显式声明。

缓存策略决策流程(SVG)

OkHttp 缓存决策流程 OkHttp 缓存决策流程图 Request CacheInterceptor CacheStrategy useNetwork useCache Network Call Cache Hit Response

缓存配置参数对比

参数类型作用默认值
maxSizelong缓存磁盘最大字节数无默认,必须指定
directoryFile缓存文件存放目录无默认,必须指定
Cache-Control: max-age秒缓存相对有效期由服务器决定
Cache-Control: max-stale秒允许使用过期缓存的最大宽限时间0
Cache-Control: min-fresh秒要求缓存剩余有效期至少多少秒0
noCacheboolean禁止使用缓存,但允许存储缓存false
noStoreboolean禁止存储和读取缓存false
调试技巧: 开启 OkHttp 日志拦截器可观察缓存命中情况,日志输出 Cache: HIT / MISS / CONDITIONAL_HIT。配合 cache.evictAll() 可清空缓存用于测试。