11

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

这很好用。

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

目前,我已经通过在请求的 Cache-Control 标头中使用“no-cache”标志显式调用新路由来解决这个问题,但这会迫使我在需要新数据之前下载新数据,如果采取了多项措施,只是为了使缓存保持最新。

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

4

4 回答 4

15

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

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

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

myApi.getSomething(forceRefresh ? "no-cache" : null);
于 2017-01-18T19:29:31.073 回答
7

现在可以通过使用该Cache.urls()函数在 OkHttp 中实现。正如文档所说:

迭代器支持 Iterator.remove()。从迭代器中删除 URL 会从缓存中驱逐相应的响应。使用它来驱逐选定的响应。

这已于2014 年 12 月下旬合并到 master中,似乎是这些标签(版本)的一部分:parent-2.4.0-RC1 parent-2.4.0 parent-2.3.0 parent-2.2.0

于 2015-07-13T11:46:14.077 回答
4

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

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

于 2014-05-21T13:14:34.103 回答
2

引用官方代码示例urls()

val urlIterator = cache.urls()
    while (urlIterator.hasNext()) {
      if (urlIterator.next().startsWith("https://www.google.com/")) {
        urlIterator.remove()
      }
    }
于 2021-06-17T03:52:37.370 回答