Home  >  Article  >  Java  >  How to use cached data with Retrofit and OKHttp offline?

How to use cached data with Retrofit and OKHttp offline?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-04 14:20:02654browse

 How to use cached data with Retrofit and OKHttp offline?

Can Retrofit with OKHttp use cache data when offline

When utilizing Retrofit and OKHttp to cache HTTP responses, difficulties might arise. Let's examine this problem and its solution:

Problem

Users may fail to read cached responses offline when using Retrofit with OKHttp. Despite having the cached JSON response, an UnknownHostException is returned.

Solution

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:

  • Remove the Vary header from the response to ensure that all HTTP methods are cached.
  • If you still encounter issues, try clearing the cache and restarting the application.

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn