本文介绍了可与OKHttp使用缓存中的数据时,离线改造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用翻新与放大器; OKHttp缓存HTTP响应。我休耕这个主旨,并结束了与此code:

I'm trying to use Retrofit & OKHttp to cache HTTP responses. I fallowed this gist and, ended up with this code:

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

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

OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setResponseCache(httpResponseCache);

api = new RestAdapter.Builder()
          .setEndpoint(API_URL)
          .setLogLevel(RestAdapter.LogLevel.FULL)
          .setClient(new OkClient(okHttpClient))
          .build()
          .create(MyApi.class);

这是MyApi与缓存控制头

And this is MyApi with the Cache-Control headers

public interface MyApi {
   @Headers("Cache-Control: public, max-age=640000, s-maxage=640000 , max-stale=2419200")
   @GET("/api/v1/person/1/")
   void requestPerson(
           Callback<Person> callback
   );

首先,我请上网查看缓存文件。正确的JSON响应和头都在那里。但是,当尝试请求下线,我总是 RetrofitError UnknownHostException异常。还有什么我应该做的,使改造读取缓存中的反应呢?

First I request online and check the cache files. The correct JSON response and headers are there. But when try to request offline, I always get RetrofitError UnknownHostException. Is there anything else I should do to make Retrofit read the response from cache?

编辑:由于OKHttp 2.0.x版本的Htt presponseCache 缓存 setResponseCache setCache

Since OKHttp 2.0.x HttpResponseCache is Cache, setResponseCache is setCache

推荐答案

事实证明,服务器的响应必须具有的Cache-Control:公开,使 OkClient 从缓存中读取。

It turns out that server response must have Cache-Control: public to make OkClient to read from cache.

此外,如果你想从网络请求可用时,您应该添加缓存控制:最大年龄= 0 请求头。 这个答案展示了如何做到这一点的参数。这是我如何使用它:

Also If you want to request from network when available, you should add Cache-Control: max-age=0 request header. This answer shows how to do it parameterized. This is how I used it:

RestAdapter.Builder builder= new RestAdapter.Builder()
   .setRequestInterceptor(new RequestInterceptor() {
        @Override
        public void intercept(RequestFacade request) {
            request.addHeader("Accept", "application/json;versions=1");
            if (MyApplicationUtils.isNetworkAvailable(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);
            }
        }
});

编辑:由于OKHttp 2.0.x版本的Htt presponseCache 缓存 setResponseCache setCache 。所以,你应该 setCache 是这样的:

Since OKHttp 2.0.x HttpResponseCache is Cache, setResponseCache is setCache. So you should setCache like this:

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

        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);
        }
        String hostURL = context.getString(R.string.host_url);

        api = new RestAdapter.Builder()
                .setEndpoint(hostURL)
                .setClient(new OkClient(okHttpClient))
                .setRequestInterceptor(/*rest of the answer here */)
                .build()
                .create(MyApi.class);

这篇关于可与OKHttp使用缓存中的数据时,离线改造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 12:32