When utilizing Retrofit and OKHttp to cache HTTP responses, difficulties might arise. Let's examine this problem and its solution:
Users may fail to read cached responses offline when using Retrofit with OKHttp. Despite having the cached JSON response, an UnknownHostException is returned.
To resolve this issue, the server response must contain Cache-Control: public to enable OkClient to access the cache.
Additionally, you can modify the request header to prioritize network connections when they are accessible by adding Cache-Control: max-age=0.
Here's how to use it explicitly:
For Retrofit 2.x:
Use an Interceptor to manage cache access:
<code class="java">private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Response originalResponse = chain.proceed(chain.request()); if (Utils.isNetworkAvailable(context)) { int maxAge = 60; // read from cache for 1 minute return originalResponse.newBuilder() .header("Cache-Control", "public, max-age=" + maxAge) .build(); } else { int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale return originalResponse.newBuilder() .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale) .build(); } } };</code>
Configure the client:
<code class="java">OkHttpClient client = new OkHttpClient(); client.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR); // Setup cache File httpCacheDirectory = new File(context.getCacheDir(), "responses"); int cacheSize = 10 * 1024 * 1024; // 10 MiB Cache cache = new Cache(httpCacheDirectory, cacheSize); // Add cache to the client client.setCache(cache); // ...</code>
For OKHttp 2.0.x:
Update the code to reflect the changes in the syntax:
<code class="java"> 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) // ... .build() .create(MyApi.class);</code>
Other Considerations:
The above is the detailed content of How to use cached data with Retrofit and OKHttp offline?. For more information, please follow other related articles on the PHP Chinese website!