Retrofit Offline Caching or Response Caching in Android

Hello friends,

Today I am posting about the caching in Retrofit, a network library in Android.

As we know caching is controlled by the Http Headers which are sent by the server in response.
Here we a use a powerful feature of Retrofit library of Intercepting the Request or Reponses.Interceptors are used to intercept and modify the request and responses.

We can use the caching in two ways -

1. There are some cases when identical request is made within a small period of time such as within 60 seconds, in such cases we can use cache to fetch the same response of the request that was fetched last time instead of makig a new API request.

2.Also we can use the response that was last fetched so that we can show the same response when the device is offline.

First create "ResponseCachingInterceptor" class that implements the Interceptor interface from okhttp class as below.
This is basically used for caching the network response for a minute.

    private static class ResponseCachingInterceptor implements Interceptor {

        @Override
            public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());
            return response.newBuilder()
                    .removeHeader("Pragma")
                    .removeHeader("Access-Control-Allow-Origin")
                    .removeHeader("Vary")
                    .removeHeader("Cache-Control")
                    .header("Cache-Control", "public, max-age=60")
                    .build();
        }
    }

Here we overiding the intercept method.
The "chain.proceed" returns the reponse of the Api request and then we modify its headers to implement caching.
First we remove some headers such as "Pragma","Cache-Control" and others to remove misconfiguration in these headers.
And then we add the "Cache-Control" header that is responsible for the caching.Here we use "max-age=60" to set the time-frame of 60 seconds.

Now we will create the "OfflineResponseCacheInterceptor" for offline cache handling as below-

          private static class OfflineResponseCacheInterceptor implements Interceptor {
           @Override            
           public okhttp3.Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                NetworkInfo networkInfo =((ConnectivityManager) 
                (context.getSystemService(Context.CONNECTIVITY_SERVICE))).getActiveNetworkInfo();
                if (networkInfo==null) {
                    request = request.newBuilder()
                            .removeHeader("Pragma")
                            .removeHeader("Access-Control-Allow-Origin")
                            .removeHeader("Vary")
                            .removeHeader("Cache-Control")
                            .header("Cache-Control",
                                    "public, only-if-cached, max-stale= 60")
                            .build();
                }
                return chain.proceed(request);
            }
        }

Here again we remove some header and the override the "Cache-Control" header as 
"public, only-if-cached, max-stale=60"
Here max-stale=60 denotes the expiration of cached response.After that time it will return with status code = 504 if network is not available otherwise it will revalidate the response from the server.


Now you can apply these interceptors to the okhttpclient as given below-

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        //Enable Response Caching
        .addNetworkInterceptor(new ResponseCachingInterceptor())
        //Enable Offline Response Caching
        .addInterceptor(new OfflineResponseCacheInterceptor())
        .cache(cache)
        .build();

And that's all we need to implement caching in Retrofit.
The above approach to caching is what Retrofit uses and it works pretty well if the right headers are sent.You just have to define the cache location and headers, everything is pretty much handled by the library.
   

Flutter : Using Form and Text Fields

Flutter is a popular cross-platform mobile development framework that allows developers to build native apps for both Android and iOS using ...