[英]OKHTTP3 Offline cache
I want to implement cache even if there is no internet connection(Offline) but still had no success, already look many example but still no luck 即使没有互联网连接(离线),我也想实现缓存,但是仍然没有成功,已经看起来很多示例,但是仍然没有运气
//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();
if offline the return comes as empty string. 如果离线,则返回为空字符串。 Is there something I miss or wrong?
有什么我想念或做错的吗?
In order to be able to reuse a cached response, it is necessary that the response itself declares itself to be "cacheable", by providing some headers (eg, Cache-Control: public
or Cache-Control: max-age=3600
). 为了能够重用缓存的响应,必须通过提供一些标头(例如,
Cache-Control: public
或Cache-Control: max-age=3600
),使响应本身声明自己为“可缓存”。 Did you check if your response contains such headers? 您是否检查过您的回复中是否包含此类标题?
Also, consider using the built-in constant CacheControl.FORCE_CACHE as a value for your cacheControl
setter . 另外,请考虑使用内置常量CacheControl.FORCE_CACHE作为您的
cacheControl
setter的值。
Finally, be aware that (quoting from OkHttp documentation ): 最后,请注意(引用OkHttp文档 ):
Be warned: if you use
FORCE_CACHE
and the response requires the network, OkHttp will return a504 Unsatisfiable Request
response警告:如果使用
FORCE_CACHE
,并且响应需要网络,则OkHttp将返回504 Unsatisfiable Request
响应
Here's a full example. 这是一个完整的例子。
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());
Please note that since this is a "standalone" example, I had to do 2 calls: 请注意,由于这是一个“独立”示例,因此我必须进行2次调用:
Note also that you need to close the response , otherwise the cache won't be populated correctly. 另请注意, 您需要关闭响应 ,否则将无法正确填充缓存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.