Wednesday, January 16, 2013

Utilizing Http response cache

     A typical mobile application will probably consume some resources from a web server using http requests. This repeated task has some drawbacks:

  • Bandwidth has a cost, polling the same data over and over again results in a waste of user’s quota.
  • the responsiveness and user experience is compromised once the user keeps waiting for data. If the requested data hasn’t changed on the server, then there’s no reason for us to fetch it.

Of course, local caching of data is a must, but we also need to be able to refresh the data if it has changed on the server.

A simple solution which comes out of the box for API 4+ is http response caching.

Http response caching is a mechanism which enables us as developers to save a footprint of the response utilizing the abilities of the Http protocol.

Basically, is holds a simple cache of the response which can be defined and enabled in code, and it prevents from fetching unchanged data from the server which was already fetched and processed into the cache.

In Android 4+ we should use the HttpUrlConnection class in order to get data from a given Url address.

first , we need to enable this feature by using the following code, preferably in a pre loading of the application, for example: in a Class which derives from the Application class , in the onCreate() method before any requests are done to the server

 

private void enableHttpCaching()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
try {
File httpCacheDir = new File(getApplicationContext().getCacheDir()
, "http");
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
HttpResponseCache.install(httpCacheDir, httpCacheSize);
} catch (IOException e) {
Log.i(Constants.TAG_REPONSE_CACHING_FAILED
, "OVER ICS: HTTP response cache failed:" + e);
}
}
else
{
File httpCacheDir = new File(getApplicationContext().getCacheDir()
, "http");
try {
com.integralblue.httpresponsecache.HttpResponseCache.install
(httpCacheDir, 10 * 1024 * 1024);
} catch (IOException e) {
Log.i(Constants.TAG_REPONSE_CACHING_FAILED
, "UNDER ICS : HTTP response cache failed:" + e);
}
}
}



notice that we perform a check for the installed Android version on the device in order to support devices with API version prior to ICS (Android 4.0), because we are using the HttpResponseCache Class.


The inner part of the method also involves creating A file to host the actual cached data.


Here as a simple example of using httpUrlConnection in order to be able to utilize the httpResopnseCache.


 

public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setUseCaches(true);
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}

7 comments:

Deepak Unnikrishnan said...
This comment has been removed by a blog administrator.
Deepak Unnikrishnan said...

Can we cache HTTP.PUT requests ? I tried using the put method in HttpResponseCache , but it returned null.

Israel Tabadi said...

I didn't try using the response cache manganonism for put requests, it should be working the same, however i would suggest reading the sdk documentation for it and maybe post a question in google groups for the android team to answer

Israel Tabadi said...

additionally, if you aren't the only client using the put requests then it makes caching a bit redundant, because that would mean that you don't care about put requests from other clients.

Deepak Unnikrishnan said...

In this particular PUT request api , an id is passed as the content of the request and based on this , the server returns HTTP_OK and also a LastModified header. So if the response is not cached ,then i won't be able to pass this as If-Modified-Since header during the next request.

Nigel said...

What about HTTPS requests?

Israel Tabadi said...

Hi Nigel,
This manganonism also supports https responses, you can have a look at the documentation here:

http://developer.android.com/reference/android/net/http/HttpResponseCache.html