如何使用 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的使用