Wednesday, April 21, 2010

Android Data Caching

One of the applications I'm building for the Android platform is meant to be used in remote regions of the developing world. While cellular coverage is getting more ubiquitous across the globe, there will inevitably be dead zones. With this in mind, all data-driven aspects of the application are being designed to degrade gracefully when there is no data connection available. One way in which this is being handled is by pre-caching data whenever possible.

Solving this problem in an application-specific manner is fairly straightforward. There are essentially 3 steps:
  • Identify those items that you can cache - Since much of the information for this application is geo-coded, deciding what to cache is usually pretty straightforward (I can, for example, pull in all the data points tagged within a given radius of the device's current position).
  • Watch for data connectivity changes and download cacheable data whenever a connection is available - registering a broadcast receiver to listen for status change messages makes this fairly trivial
  • Store data locally that needs to be sent and send it whenever you have a data connection - again, a broadcast receiver makes this simple.

Beyond this core functionality, I've also built some ancillary features to allow users to better control their bandwidth usage in the event that they're not on an unlimited plan (a user can opt to only perform cache downloads if they have a WiFi connection as opposed to a cellular connection and they can choose what types of data they want to cache).

While this works well for the application, the real problem I'd like to address is doing this in a generic, reusable fashion. I haven't done so yet, but I am planning on building a library that can handle both cache population and data upload. The library would handle the nuts and bolts of listening to status changes and initiating downloads/uploads based on user preferences while delegating the decision of what to download (and how to do it) to user-supplied helper classes. These helpers can extend a base CacheAwareHelper class that, on invocation can first check to see if the data is already in cache and, if not, then invoke the method that actually performs the fetch of the data from the remote location. The result, in addition to being returned to the calling method, can then be cached.

This is still just a thought and I'm sure the details will flex a bit once I start writing the real design and implementation. I am still thinking about how to handle cache invalidation such that things are only evicted when they absolutely need to be. Stay tuned for a follow-up post once the library is done. At that time I'll include a few diagrams to show how it works. If anyone is actually reading this blog, I'd love to hear some feature suggestions in the comments as I'm planning on releasing this library as open-source.

1 comment:

  1. Great idea. I wish more Apps would take this approach. Would be nice if you could configure how much pre-fetching the App would do (based on networks type / cost of data).

    ReplyDelete