首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OKHTTP3脱机缓存

OKHTTP3脱机缓存
EN

Stack Overflow用户
提问于 2018-02-27 14:50:51
回答 1查看 583关注 0票数 0

我想实现缓存,即使没有互联网连接(离线),但仍然没有成功,已经看了很多例子,但仍然没有运气

代码语言:javascript
复制
//FeedInterceptor Class 
public static Interceptor getOfflineInterceptor(final Context context){
    Interceptor interceptor = new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (!isNetworkAvailable(context)) {
                request = request.newBuilder()
                        .removeHeader("Pragma")
                        .header("Cache-Control", "public, only-if-cached")
                        .build();
            }
            return chain.proceed(request);
        }
    };

    return interceptor;
}


//OnCreate Activity
client = new OkHttpClient.Builder()
            .addNetworkInterceptor(FeedInterceptor.getOnlineInterceptor(this))
            .addInterceptor(FeedInterceptor.getOfflineInterceptor(this))
            .cache(cache)
            .build();

//After build Request
Response response = client.newCall(request).execute();
return response.body().string();

如果脱机,则返回为空字符串。我是不是遗漏了什么,或者说错了什么?

EN

回答 1

Stack Overflow用户

发布于 2018-02-27 22:21:52

为了能够重用缓存的响应,有必要通过提供一些头部(例如,Cache-Control: publicCache-Control: max-age=3600)来声明响应本身是“可缓存的”。你有没有检查你的响应是否包含这样的报头?

另外,考虑使用内置常量CacheControl.FORCE_CACHE作为cacheControl setter的值。

最后,请注意(引用自OkHttp documentation):

注意:如果您使用FORCE_CACHE并且响应需要网络,则OkHttp将返回504 Unsatisfiable Request响应

编辑:

这里有一个完整的例子。

代码语言:javascript
复制
final CacheControl cacheControl = new CacheControl.Builder()
        .maxAge(60, TimeUnit.MINUTES)
        .build();

// Interceptor to ask for cached only responses
Interceptor cacheResponseInterceptor = chain -> {
    Response response = chain.proceed(chain.request());
    return response.newBuilder()
            .header("Cache-Control", cacheControl.toString())
            .build();
};

// Interceptor to cache responses
Interceptor cacheRequestInterceptor = chain -> {
    Request request = chain.request();
    request = request.newBuilder()
            .cacheControl(CacheControl.FORCE_CACHE)
            .build();

    return chain.proceed(request);
};

// Create a directory to cache responses. Max size = 10 MiB
Cache cache = new Cache(new File("okhttp.cache"), 10 * 1024 * 1024);

/*
 * Let's create the client. At the beginning the cache will be empty, so we will
 * add the interceptor for the request only after, for the 2nd call
 */
OkHttpClient client = new OkHttpClient.Builder()
        .cache(cache)
        .addNetworkInterceptor(cacheResponseInterceptor)
        .build();

// Let's do the call
Request request = new Request.Builder()
        .url("http://httpbin.org/get")
        .get()
        .build();
Response response = client.newCall(request).execute();
response.close();

// Let's add the interceptor for the request
client = client.newBuilder()
        .addInterceptor(cacheRequestInterceptor)
        .build();

// Let's do the same call
request = new Request.Builder()
        .url("http://httpbin.org/get")
        .get()
        .build();
response = client.newCall(request).execute();
response.close();

// Let's see if we had some issues with the cache
System.out.println("Is successful? " + response.isSuccessful());

请注意,由于这是一个“独立”示例,我必须执行两次调用:

  1. 此调用使用网络获取对缓存的有效响应,否则我的缓存将为空。在你的例子中,你不需要它,因为通常你会使用设备数据来做一个“真正的”调用;请注意,这里我使用了网络拦截器,它添加了标头"ok,你可以缓存这个响应“。
  2. I添加了强制使用缓存的拦截器。这里将不使用网络拦截器,因为要么在缓存中找到响应,要么返回504响应。

还要注意,您需要关闭响应,否则缓存将无法正确填充。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49002769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档