首页 > 解决方案 > ony-if-cached 错误:通过改造实现缓存

问题描述

我对编码/android 开发比较陌生,我正在尝试第一次在我的应用程序中实现缓存。该应用程序当前每次打开时都会调用数据库,以获取一些可以在会话之间轻松缓存和存储的基本信息。

我认为最简单的解决方案是通过改造实现缓存,如下所述:https ://medium.com/mindorks/caching-with-retrofit-store-responses-offline-71439ed32fda我希望能够修改它以检查是否缓存中有未过期的数据,只有在数据过期时才调用数据库。与手机离线时使用缓存相反。

到目前为止,这就是我所拥有的

OkHttpClient = OkHttpClient.Builder().connectTimeout(timeout.toLong(), TimeUnit.SECONDS).run {
        context?.let { context ->
                cache(Cache(context.cacheDir, (5 * 1024 * 1024).toLong()))
                addInterceptor {
                    it.proceed(it.request().newBuilder().header("Cache-Control", "private, only-if-cached, max-stale=" + 60*60*24*28).build())
                }

我希望这会检查缓存中是否有数据,如果没有则进行调用,但是我从数据库中得到了 504 错误响应。我想我错过了一些关键步骤,但我不确定它们是什么。任何帮助都会很棒。谢谢

标签: androidcachingkotlin

解决方案


我对每个拦截器如何工作的来龙去脉不是很熟悉,但我摆弄/搜索,直到我发现使用两个拦截器对我有用的东西。我的部分实现是能够强制刷新,这是您在第一个拦截器中看到的布尔值

科特林:

...
val cacheControl = CacheControl.Builder().maxAge(timeUnit.toSeconds(cacheDuration), TimeUnit.SECONDS).build()

cache(Cache(File(context?.cacheDir, "http-cache"), CACHE_SIZE.toLong()))
// Adding both interceptors ensures the FORCE_NETWORK to call the api through the network and override the cache with new data
addInterceptor { chain -> chain.proceed(chain.request().newBuilder().header("Cache-Control", if (!useCache) CacheControl.FORCE_NETWORK.toString() else cacheControl.toString()).build()) }
//The 'Pragma' header key has a no-cache value in some APIs so it must be removed for us to cache it
addNetworkInterceptor { chain -> chain.proceed(chain.request()).newBuilder().removeHeader("Pragma").header("Cache-Control", cacheControl.toString()).build() }
...

推荐阅读