如何使用OKHttp进行改造在离线时使用缓存数据

时间:2015-07-09 15:30:56

标签: android caching gzip retrofit okhttp

我希望使用OkHttp进行改造,在没有互联网时使用缓存。

我准备这样的OkHttpClient:

    RestAdapter.Builder builder= new RestAdapter.Builder()
       .setRequestInterceptor(new RequestInterceptor() {
            @Override
            public void intercept(RequestFacade request) {
                request.addHeader("Accept", "application/json;versions=1");
                if (MyApplicationUtils.isNetworkAvaliable(context)) {
                    int maxAge = 60; // read from cache for 1 minute
                    request.addHeader("Cache-Control", "public, max-age=" + maxAge);
                } else {
                    int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
                    request.addHeader("Cache-Control", 
                        "public, only-if-cached, max-stale=" + maxStale);
                }
            }
    });

并像这样设置缓存:

   Cache cache = null;
    try {
        cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024);
    } catch (IOException e) {
        Log.e("OKHttp", "Could not create http cache", e);
    }

    OkHttpClient okHttpClient = new OkHttpClient();
    if (cache != null) {
        okHttpClient.setCache(cache);
    }

我在rooted设备上检查过,在缓存目录中是使用“Response headers”和Gzip文件保存文件。

但我没有从离线改造缓存中得到正确的答案,尽管在GZip文件中编码了我的正确答案。那么我如何才能让Retrofit能够读取GZip文件,以及如何知道它应该是哪个文件(因为我有一些文件和其他响应)?

1 个答案:

答案 0 :(得分:24)

我公司有类似问题:)

问题出在服务器端。在serwer响应中,我有:

Pragma: no-cache

所以当我删除它时,一切都开始工作了。在我删除它之前,我总是得到这样的例外:504 Unsatisfiable Request (only-if-cached)

好的,我的实施方式如何。

    OkHttpClient okHttpClient = new OkHttpClient();

    File httpCacheDirectory = new File(appContext.getCacheDir(), "responses");

    Cache cache = new Cache(httpCacheDirectory, maxSizeInBytes);
    okHttpClient.setCache(cache);

    OkClient okClient = new OkClient(okHttpClient);

    RestAdapter.Builder builder = new RestAdapter.Builder();
    builder.setEndpoint(endpoint);
    builder.setClient(okClient);

如果您在测试问题(服务器或应用程序)方面遇到问题。您可以使用此类功能设置从服务器接收的标头。

private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Response originalResponse = chain.proceed(chain.request());
        return originalResponse.newBuilder()
                               .removeHeader("Pragma")
                               .header("Cache-Control",
                                       String.format("max-age=%d", 60))
                               .build();
    }
};

然后简单地添加它:

okHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR);

感谢您,因为您可以看到我能够在测试时删除Pragma: no-cache标题。

另外,我建议您阅读Cache-Control标题:

max-agemax-stale

其他有用的链接:

List of HTTP header fields

Cache controll

Another sample code