title: Get response from cache when network is slow using Okhttp and Retrofit
body: <p>I need my first API request to take the response from the cache if it's available and else get the response from the network. If the response is taken from cache it should be updated later. How can I implement this? please help me or give me some suggestions to implement this.</p>
  
  <p>Below given is the code I have implemented for caching the response using okhttp and retrofit.</p>
  
  <pre><code>public class RetrofitClient {
  
    private static Retrofit retrofit = null;
    private final static int CACHE_SIZE_IN_BYTE = 5 * 1024 * 1024; // 5 MB
  
    public static Retrofit getClient(String baseUrl) {
      if (retrofit == null) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addNetworkInterceptor(new ResponseCacheInterceptor())
            .addInterceptor(new OfflineResponseCacheInterceptor())
            .addInterceptor(getLoggingInterceptor())
            // Set the cache location and size (5 MB)
            .cache(new Cache(new File(MyApp.getAppContext().getCacheDir(), "apiResponses"),
                CACHE_SIZE_IN_BYTE))
            .build();
  
        retrofit = new Retrofit.Builder().baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build();
      }
      return retrofit;
    }
  
    /**
     * Interceptor to cache data and maintain it for a minute.
     *
     * If the same network request is sent within a minute,
     * the response is retrieved from cache.
     */
    private static class ResponseCacheInterceptor implements Interceptor {
      @Override public okhttp3.Response intercept(Chain chain) throws IOException {
        okhttp3.Response originalResponse = chain.proceed(chain.request());
        return originalResponse.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
      }
    }
  
    /**
     * Interceptor to cache data and maintain it for four weeks.
     *
     * If the device is offline, stale (at most four weeks old)
     * response is fetched from the cache.
     */
    private static class OfflineResponseCacheInterceptor implements Interceptor {
      @Override public okhttp3.Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (!MyApp.isOnline()) {
          request = request.newBuilder()
              .header("Cache-Control", "public, only-if-cached, max-stale=" + 2419200)
              .build();
        } else {
          request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
        }
        return chain.proceed(request);
      }
    }
  
    private static HttpLoggingInterceptor getLoggingInterceptor() {
      return new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
    }
  }
  </code></pre>