You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin MultiPlatform中基于Ktor实现可自定义过期时间的缓存机制?

Ktor在KMM项目中的缓存实现与定制

核心结论

Ktor完全支持在Kotlin MultiPlatform项目中实现网络缓存,并且支持自定义缓存过期时间、缓存策略等多种定制需求,所有配置均可在共享业务逻辑模块中完成,无需针对iOS/Android做额外平台适配。

基础缓存实现

首先在共享模块的Ktor客户端中添加官方提供的HttpCache插件,这是基于HTTP缓存规范实现的原生缓存方案:

val client = HttpClient(OkHttp) {
    install(HttpCache) {
        // 配置缓存存储目录与上限(KMM中可使用平台特定临时目录或跨平台存储库)
        cacheStorage = CacheStorage(
            directory = File(System.getProperty("java.io.tmpdir"), "ktor-shared-cache"),
            maxSize = 50L * 1024 * 1024 // 设置50MB缓存上限
        )
    }
}

自定义缓存过期时间

有两种常用方式控制缓存过期:

  1. 遵循后端响应头规则:后端通过返回Cache-Control头指定过期策略,Ktor会自动适配。例如后端返回:

    Cache-Control: max-age=3600, public
    表示该响应可被公共缓存存储,且1小时内有效。

  2. 客户端强制覆盖规则:如果需要忽略后端缓存头,可在发起请求时自定义缓存策略:

client.get("https://api.example.com/user-data") {
    cacheControl {
        maxAge(2, TimeUnit.HOURS) // 强制缓存2小时
        // 还可配置noCache(每次验证缓存)、noStore(禁止缓存)等策略
    }
}

其他定制需求

  • 自定义缓存存储逻辑:若默认文件存储不满足需求,可实现CacheStorage接口对接跨平台数据库(如SQLDelight)或其他存储方案:
class SqlDelightCacheStorage(private val db: AppDatabase) : CacheStorage {
    override suspend fun get(url: Url, varyKeys: List<String>): CachedResponseData? {
        // 从SQLDelight数据库读取对应缓存数据
        return db.cacheQueries.getCache(url.toString()).executeAsOneOrNull()?.toCachedResponse()
    }

    override suspend fun put(url: Url, varyKeys: List<String>, data: CachedResponseData) {
        // 将缓存数据写入SQLDelight数据库
        db.cacheQueries.insertCache(
            url = url.toString(),
            data = data.toByteArray(),
            expireTime = System.currentTimeMillis() + data.cacheControl.maxAge!!.inWholeMilliseconds
        )
    }

    override suspend fun remove(url: Url, varyKeys: List<String>) {
        db.cacheQueries.deleteCache(url.toString())
    }
}

// 在客户端中使用自定义存储
val client = HttpClient(OkHttp) {
    install(HttpCache) {
        cacheStorage = SqlDelightCacheStorage(AppDatabase())
    }
}
  • 自定义缓存键:通过cacheKey配置生成唯一缓存标识,避免不同请求共用缓存(比如结合用户身份、请求参数):
install(HttpCache) {
    cacheKey { request ->
        // 结合URL、查询参数和用户Token生成唯一缓存键
        "${request.url}?params=${request.url.parameters}&token=${request.headers["Authorization"]}"
    }
}
  • 主动清空缓存:调用插件的clear方法可一键清空所有缓存:
client.plugin(HttpCache).clear()

内容的提问来源于stack exchange,提问作者Android Killer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:27:14