Offline Caching

Opening your application with no internet and seeing no previous data is a very common occurrence.
Two ways to deal with loading network requests that come first to our minds are:

Shared Preferences

SQLite

Using either of them comes with its fair share of cons (and more code to write).

While Adding Data in SharedPreferences is easy. It’s time-consuming to retrieve the required data. Plus scalability is an issue.

SQLite with tables makes it hard to do many changes in the future. Plus SQLite operations are heavy.

Why use both when OkHtttp caches the HTTP responses built-in?

Caching Requests

We know that OkHttp is the default HttpClient for Retrofit.
OkHttp comes with a powerful component Interceptors.

Interceptors are generally of two types:

Application Interceptors – Gets you the final response.

Network Interceptors – To intercept intermediate requests.

Using Interceptors you can read and modify the requests. And obviously, we’ll add Cache control on the responses.

Cache-control is an header used to specify caching policies in client requests and server responses.

You cannot cache POST requests. Only GET requests can be cached.

Inside the interceptors, you need to get chain.request() to get the current request and add Cache options to it.

For example, we can add a header “Cache-Control” to the request as: "public, only-if-cached, max-stale=60"

Then do a chain.proceed(request) to proceed with the modified request to return the response.

max-age vs max-stale

max-age is the oldest limit ( lower limit) till which the response can be returned from the cache.max-stale is the highest limit beyond which cache cannot be returned.

In the following section, we’ll do a Retrofit Request with OkHttp as the Client and using RxJava.
We’ll cache the requests such that they can be displayed the next time if there is no internet/problem in getting the latest request.

The order of the interceptors in the OkHttpClient Builder is important.
The addNetworkInterceptor adds the cache control to the request.

In the addInterceptor, provideOfflineCacheInterceptor is called. If there is an exception which would typically be a ConnectException or a NoRouteFoundException, the request is retried again, this time with a header to get the response from the Cache.

Popular Categories

Newsletter for You

Don't miss out!

Subscribe To Newsletter

We promise not to spam you. Unsubscribe at any time.

Invalid email address

Thanks for subscribing!

JournalDev is one of the most popular websites for Java, Python, Android, and related technical articles. Our tutorials are regularly updated, error-free, and complete. Every month millions of developers like you visit JournalDev to read our tutorials.

JournalDev was founded by Pankaj Kumar in 2010 to share his experience and learnings with the whole world. He loves Open source technologies and writing on JournalDev has become his passion.