Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Android Response Caching using Retrofit 1.9 + OkHttp 2.2

Android REST Controller with Cache-Control

Android REST Controller with Simple Cache Control Headers using Retrofit 1.9.0 + OkHttp 2.2.0

public abstract class RestController {
private static Context mContext;
private static long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MB
protected static RestAdapter mRestAdapter;
public static void init(final Context context, String baseAPIUrl) {
mContext = context;
// Create Cache
Cache cache = null;
try {
cache = new Cache(new File(mContext.getCacheDir(), "http"), SIZE_OF_CACHE);
} catch (IOException e) {
Log.e(RestController.class.getSimpleName(), "Could not create Cache!", e);
}
// Create OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setCache(cache);
okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(30, TimeUnit.SECONDS);
// Add Cache-Control Interceptor
okHttpClient.networkInterceptors().add(mCacheControlInterceptor);
// Create Executor
Executor executor = Executors.newCachedThreadPool();
mRestAdapter = new RestAdapter.Builder()
.setEndpoint(baseAPIUrl)
.setExecutors(executor, executor)
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
}
private static final Interceptor mCacheControlInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// Add Cache Control only for GET methods
if (request.method().equals("GET")) {
if (ConnectivityHelper.isNetworkAvailable(mContext)) {
// 1 day
request.newBuilder()
.header("Cache-Control", "only-if-cached")
.build();
} else {
// 4 weeks stale
request.newBuilder()
.header("Cache-Control", "public, max-stale=2419200")
.build();
}
}
Response response = chain.proceed(request);
// Re-write response CC header to force use of cache
return response.newBuilder()
.header("Cache-Control", "public, max-age=86400") // 1 day
.build();
}
};
}
@wh5355

This comment has been minimized.

Copy link

@wh5355 wh5355 commented Aug 25, 2015

good.

@praveen18p

This comment has been minimized.

Copy link

@praveen18p praveen18p commented Nov 3, 2015

I tried this example, I want to make fresh network call and cache the data ,in case if there is no network it should pick from cache .

But using this code it always returns from cache .

Is there any way in which i can achieve this

@polbins

This comment has been minimized.

Copy link
Owner Author

@polbins polbins commented Nov 12, 2015

@praveen18p - you have to remove them manually, something like this:

public static void removeFromCache(String urlString) {
    try {
        Iterator<String> it = mCache.urls();

        while (it.hasNext()) {
            String next = it.next();

            if (next.contains(urlString)) {
                it.remove();
            }   
        }   
    } catch (IOException e) {
        e.printStackTrace();
    }   
}

each cache is stored via its URL

@ismdcf

This comment has been minimized.

Copy link

@ismdcf ismdcf commented May 18, 2016

Do we need to have the "Cache-Control" header in the HTTP response we receive, or will it work for responses without the cache-control header.

@kzdeveloper12345

This comment has been minimized.

Copy link

@kzdeveloper12345 kzdeveloper12345 commented Feb 15, 2018

Interceptor not work for this code
Please , help me how to make
mCacheControlInterceptor is not worked .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment