如何使用 Retrofit 和 OKHttp 在下一次请求时使缓存路由无效/强制更新?

Posted

技术标签:

【中文标题】如何使用 Retrofit 和 OKHttp 在下一次请求时使缓存路由无效/强制更新?【英文标题】:How to invalidate/force update of cache route at next request with Retrofit and OKHttp? 【发布时间】:2014-07-10 01:21:56 【问题描述】:

我正在使用带有 OKHttp 客户端的 Retrofit 来缓存来自 JSON API 的响应。

这很好用。

但是,如果我在设备上采取了导致数据在服务器上更新的操作,我需要一种方法来“使”特定路由“无效”,以确保下次对该数据发出请求时,它是再次从服务器获取,而不是现在过时的缓存版本。

目前,我通过在请求的 Cache-Control 标头中使用“no-cache”标志显式调用新路由来解决此问题,但这迫使我在需要之前下载新数据,可能如果执行多个操作,则多次执行,只是为了使缓存保持最新。

有没有办法可以将我的改造/OKhttp 客户端中的路由/方法标记为缓存已过期,下次请求时需要通过网络强制更新?

【问题讨论】:

【参考方案1】:

使用 retrofit2 和 OkHttp3,您可以通过在 API 方法定义参数中添加 Cache-Control 标头来强制执行新响应:

@GET("ws/something")
Something getSomething(@Header("Cache-Control") String cacheControl);

然后在给您打电话时,请提供null(可能是)缓存版本或"no-cache" 提供实时版本:

myApi.getSomething(forceRefresh ? "no-cache" : null);

【讨论】:

很好的解决方案! 这个不会缓存刷新数据,怎么缓存刷新数据 @Sam 的评论有什么解决办法了吗? FWIW,在轻度测试中,no-cache 不会阻止 OkHttp 缓存响应。根据 OkHttp 源代码,no-store 将阻止 OkHttp 缓存响应。【参考方案2】:

现在可以在 OkHttp 中使用 Cache.urls() 函数。正如the documentation 所说:

迭代器支持 Iterator.remove()。从 迭代器从缓存中驱逐相应的响应。用这个来 驱逐选定的响应。

这是 merged into master 2014 年 12 月下旬,似乎是这些标签(发布)的一部分:parent-2.4.0-RC1 parent-2.4.0 parent-2.3.0 parent-2.2.0 em>

【讨论】:

【参考方案3】:

没有用于此的 API,但应该有。请open 一个 OkHttp 问题报告此问题。

我们可能需要一些时间来实现,因为我们需要找出最好的 API 是什么。使单个 URL 无效很简单。使一系列 URL 无效(比如square.com/cash/*)更加困难,因为 OkHttp 的缓存当前是由 URL 校验和组织的。还有一些丑陋的边缘情况,例如如果无效的 URL 当前正在写入缓存会发生什么。

【讨论】:

感谢您的及时回复。我已按要求创建了一个问题:github.com/square/okhttp/issues/853 请参阅***.com/a/68012702/12528345 以获取所请求功能的代码示例(***.com/questions/23782531/… 中提到的问题已解决并实现了该功能)。【参考方案4】:

使用urls()引用the official code sample:

val urlIterator = cache.urls()
    while (urlIterator.hasNext()) 
      if (urlIterator.next().startsWith("https://www.google.com/")) 
        urlIterator.remove()
      
    

【讨论】:

以上是关于如何使用 Retrofit 和 OKHttp 在下一次请求时使缓存路由无效/强制更新?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OkHttp/Retrofit 重试 HTTP 请求?

Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用

Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用

使用OkHttp拦截器和Retrofit进行缓存

使用OkHttp拦截器和Retrofit进行缓存

retrofit和okhttp请求url的参数拼接