HTTP Response Caching for Java and Android
HTTP caching is both important, as it reduces bandwidth use and improves performance, and complex, as the rules are far from simple. In my experience, most Java and Android applications either don’t do HTTP caching, or they roll their own and up doing it wrong or in way too complicated a fashion. In other words, they create a non-standard, one off, unmaintainable solution. And IMHO, that’s no solution at all.
If you find yourself using HttpClient, you can use HttpClient-Cache, which is an easy drop in for Java. See my previous post about HttpClient-Cache for Android. But if you’re using HttpUrlConnection (aka java.net.URL.openConnection()), there’s no good solution for regular Java or Android. Well, in Android 4.0 and later, you can use HttpResponseCache, but with only a small percentage of Android devices using 4.0 or later, that’s not a terribly good solution. If you use Android 4.0+’s HttpResponseCache as recommended by Google, then all previous Android versions end up with no HTTP response caching – this causes excess load on your servers, slower performance for the app, and unnecessary bandwidth use.
To fix this problem, I grabbed all the code from AOSP that implements Android 4.0′s HttpResponseCache and made it a separate library. This library is easy to use, works on Java 1.5+, all versions of Android, and is licensed under APLv2 (just like everything else in AOSP). Really, there’s no reason not to use it! You can even use in Java server applications, such as those that use Spring.
To use it, if you’re using Maven, simply add this block to your pom.xml (all artifacts are in Maven Central):
<dependency>
<groupId>
<com.integralblue</groupId>
<artifactId>httpresponsecache</artifactId>
<version>1.0.0</version>
</dependency>
If you’re not using Maven, you’ll need to add the httpresponsecache jar and its dependency, disklrucache.jar, to your project.
When your application starts, before it makes any HTTP requests, execute this method:
com.integralblue.httpresponsecache.HttpResponseCache.install(File directory, long maxSize);
If you’re using Android, and you want to use Android 4.0′s HttpResponseCache if it’s available, and fallback to this library if it’s not available:
final long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
final File httpCacheDir = new File(getCacheDir(), "http");
try {
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception httpResponseCacheNotAvailable) {
Ln.d(httpResponseCacheNotAvailable, "android.net.http.HttpResponseCache not available, probably because we're running on a pre-ICS version of Android. Using c$
try{
com.integralblue.httpresponsecache.HttpResponseCache.install(httpCacheDir, httpCacheSize);
}catch(Exception e){
Ln.e(e, "Failed to set up com.integralblue.httpresponsecache.HttpResponseCache");
}
}
The source code to the library is available on GitHub. I’m already using it in my CallerID Android app. If you end up using this library, please leave me a comment.
That’s it – enjoy easy to use HTTP caching!

The HTTP Response Caching for Java and Android by Craig Andrews, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
Unfortunately, since HttpUrlConnection doesn’t work well on Android 2.3, I am forced to depend on HttpClient instead.
HttpClient-Cache may be an easy drop-in on desktop implementations of Java – it is not an easy drop-in on Android. It depends on classes in the latest version of HttpClient that are not in the builtin Android classes and it is difficult to override them.
The HttpResponseCache library replaces the Android provided HttpUrlConnection implementation with the HttpUrlConnection implementation from Android 4.0. So if you’re concerned about problems that are in Android 2.3 that have been fixed in Android 4.0, then by using HttpResponseCache, you won’t have to worry about any of those possible Android 2.3 issues.
I highly recommend that you do not use HttpClient (or HttpClient-Cache) as Android will not be maintaining its HttpClient library. Android HttpClient library has bugs that will not be fixed, and its not compatible with HttpClient-Cache as you noticed.
Also, it was just reported to me that version 1.1 doesn’t work on Android API < 9. I have fixed that bug and intend to release a new version shortly. Here's the bug: https://github.com/candrews/HttpResponseCache/issues/15
It may be silently failing. If you look at the logcat output, you may see a stack trace. It’s possible for the cache to fail, but not affect your app in any other way than not caching.
Hi Craig.
I’ve created an issue in git hub. The issue is issue#16. I’ve included the stack as well.
Let me know if you need anything else.
I’m trying the library as a drop in replacement, I can see it is writing files to the cache I’ve set up, but I’m looking for a perf statistics and behavior to see if its working as I expect. First, is there a sample that has consistent behavior to ensure I’m using it properly?
Secondly, despite seeing the written out cached files, the statistics reported are always zeros for network/hits/requests. I’ve tried looking at both:
com.integralblue.httpresponsecache.HttpResponseCache.getInstalled();
and
com.integralblue.httpresponsecache.HttpResponseCache.getDefault();
Both of which are non-null.
Thoughts?
Thanks,
Kenny
I don’t have an example project that only shows this library being used. However, if you install using com.integralblue.httpresponsecache.HttpResponseCache.install(httpCacheDir, httpCacheSize); and then look at the stats, you should see it being used. If you find a bug, please let me know! Known issues can be found and new issues reported at https://github.com/candrews/httpresponsecache
final long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
final File httpCacheDir = new File(getCacheDir(), “http”);
try {
Class.forName(“android.net.http.HttpResponseCache”)
.getMethod(“install”, File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception httpResponseCacheNotAvailable) {
Ln.d(httpResponseCacheNotAvailable, “android.net.http.HttpResponseCache not available, probably because we’re running on a pre-ICS version of Android. Using c$
try{
com.integralblue.httpresponsecache.HttpResponseCache.install(httpCacheDir, httpCacheSize);
}catch(Exception e){
Ln.e(e, “Failed to set up com.integralblue.httpresponsecache.HttpResponseCache”);
}
}
But in ICS I am getting the HttpResponseCache.getInstalled() returning null. If i use this library on pre ICS version its working fine. Please provide any suggestion to make it work on ICS as well.
I hope that helps!
It wasn’t clear if using the built in version would take advantage of the cache and the fixes to issues in older versions.
Thanks for the help and the great library.