1

我从 Android 中的缓存和 Retrofit/OKHttp3 开始。我们需要为我们的应用程序支持离线模式/服务器关闭,我正在尝试弄清楚如何正确配置缓存以支持它。这个想法是在服务器可用时从服务器获取新副本(如果没有任何更改,则为 304)。如果服务器关闭或应用程序离线,我们需要获取缓存的响应。

我像这样配置了缓存控制:

Cache-Control: no-transform, max-age=0, max-stale=50, private

这工作得很好,但我不明白为什么即使“max-stale”已经过去,OKHttp 也会提供缓存的响应?我认为 50 秒后我会收到一个 504 - Unsatisfiable request 因为 max-stale period 已经过去了?

这是我用于 OKHttp 的拦截器:

.addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        try {
                            if (!NetworkUtil.isNetworkAvailable(model.getApplicationContext())) {
                                return getCachedResponse(chain);
                            }
                            Request request = chain.request();
                            return chain.proceed(request);
                        } catch (Exception exception) {
                            return getCachedResponse(chain);
                        }
                    }
                })

    private static Response getCachedResponse(Interceptor.Chain chain) throws IOException {
    Request request = chain.request().newBuilder()
            .cacheControl(CacheControl.FORCE_CACHE)
            .removeHeader("Pragma")
            .build();

    Response forceCacheResponse = chain.proceed(request);
    return forceCacheResponse.newBuilder()
            .build();
}

任何想法如何配置缓存,以便在最大陈旧期过后它不会提供缓存的响应?

4

1 回答 1

3

与往常一样,在您提出问题后,您会找到答案。我知道,即使在最大陈旧期过后,缓存也会继续提供内容,因为我使用了 CacheControl.FORCE_CACHE。这添加了一个“仅当缓存”标志,并且还将 max-stale 设置为一个非常高的值,该值会覆盖服务器首先传递的 max-stale 值。我通过使用我定义的 max-stale 值创建另一个缓存控件来解决它:

    private static Response getCachedResponse(Interceptor.Chain chain) throws IOException {

    CacheControl cacheControl = new CacheControl
            .Builder()
            .onlyIfCached()
            .maxStale(5, TimeUnit.MINUTES).build();

    Request request = chain.request().newBuilder()
            .cacheControl(cacheControl)
            .removeHeader("Pragma")
            .build();

    Response forceCacheResponse = chain.proceed(request);
    return forceCacheResponse.newBuilder()
            .build();
}
于 2016-02-10T12:20:01.760 回答