Let’s cut to the chase: State management on Android is tricky. From a developer’s perspective I don’t believe that the issue is so much a technical one as it is a matter of familiarity. The Activity life-cycle on Android is unlike anything I’ve seen on any other platform. It’s not intuitive, and if you spend much time in the Android code forums, you’ll find that the management (and mismanagement) of application state comes up time and time again.
On two previous occasions, I’ve mentioned that there are three keys to managing state in your Android application. Those are:
This post on long-running I/O marks the last (and most difficult) tutorial in the series.
What is long-running I/O?
Well, it can be any sort of task that if ran on the current activity’s UI thread would cause the application to appear non-responsive to the user. A common example is making a call to an external webservice. If it takes 10 seconds for you to request, retrieve, and parse results from a URL, you certainly can’t have your user interface locked up for that amount of time.
On most platforms the way long-running I/O is typically handled is to spawn the I/O off on a background thread, and let that thread call back or message the UI when the task is complete. The issue with Android is, if your user takes an action that restarts the activity life-cycle (such as rotating the phone), the reference the background thread holds becomes invalid. Any attempt to reference that pointer from the I/O thread results in a crash.
Over time, a number of techniques have evolved for dealing with this scenario. I’ve tried several, including rolling my own thread logic, using background services, and Android’s asynchronous task manager. Each approach has its pros and cons, but in general I’ve found that the AsyncTask class is a bit easier to get my head around, and it tends to be well suited for a large range of applications. The following tutorial demonstrates using an inner static extension of AsyncTask to handle long-running I/O. At times, the code may seem a bit convoluted, but hopefully by the time we are finished you’ll start to see how AsyncTask can make your life easier. If you’d like to simply download and import the project you may do so here.