问题
I want to know how can okHTTP response from Web server (which returns json data) be cached?
I want my app to download all the data needed for RecycleView and cache it once the user runs the app first time - and avoid re-downloading and parsing all the same data from Web server, if data has not changed.
I tried to get response headers, but this is what I get:
Request URL: https://somedomain.com/wp-json/?categories=3&per_page=100&status=publish
Request Method: GET
Status Code: 200 OK
Remote Address: 176.28.12.139:443
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages
Allow: GET
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json; charset=UTF-8
Date: Fri, 23 Mar 2018 15:41:23 GMT
Link: <https://somedomain.com/wp-json/>; rel="https://api.w.org/"
Server: nginx
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: PleskLin
X-Powered-By: PHP/7.1.15
X-Robots-Tag: noindex
X-WP-Total: 43
X-WP-TotalPages: 1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: hr,en-US;q=0.9,en;q=0.8,de;q=0.7,nb;q=0.6
Connection: keep-alive
Host: somedomain.com
Referer: https://somedomain.com/somedir/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
categories: 3
per_page: 100
status: publish
I have read that I could find ETAG or Last-Modified from the Server response to check for any changes, but as you can see there is no such thing.
Do you have any idea what to do if app only needs to download data at the first run - and after that only if the data has changed?
回答1:
You need cache interceptor like this:
public class CacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(15, TimeUnit.MINUTES) // 15 minutes cache
.build();
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", cacheControl.toString())
.build();
}
}
Add this interceptor with Cache
to your OkHttpClient
like this:
File httpCacheDirectory = new File(applicationContext.getCacheDir(), "http-cache");
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addNetworkInterceptor(new CacheInterceptor())
.cache(cache)
.build();
回答2:
Just add a cache to your OkHttp client. First, you'll need to create the cache:
int cacheSize = 10 * 1024 * 1024;
Cache cache = new Cache(cacheDirectory, cacheSize);
Note that with this code you're providing a cache with a size limit of 10MB. After this, you'll create your client with the following code:
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
The client will honor cache related headers. You can relate to the official documentation for further details: https://github.com/square/okhttp/wiki/Recipes
来源:https://stackoverflow.com/questions/49453564/how-to-cache-okhttp-response-from-web-server