My last note (“Long Computations in the Main Android Thread“) explained one way to take an expensive operation and move it to a background task. Since writing that, I have learned about the AsyncTask class. It is much easier way to do the same thing.
AsyncTask gives you an easy way to start a background task to do something that you don’t want running on the UI thread. Complete documentation is available on the Android Developers website: AsyncTask. It’s pretty clear from that what you have to do.
If you are looking for a working example, I have built one and posted the source code at the end of this note. A few points about my example:
- It illustrates the important aspects of AsyncTask: starting a task, publishing progress, etc.
- It shows how to cancel the running task.
- It shows how to cancel a running task when your activity is paused or stopped.
The app is shown in Figure 1. It has four rectangular views that change colors when you press the Start button. It runs for about 2000 iterations or until you press the Stop button.
Figure 1
It’s really not that computationally intensive to choose one of the four views at random, but I wanted to make sure I understood the mechanics in a simple case before I tried it out in the game I am working on. In the game, generating a move can take several seconds to calculate.
One of the reasons I didn’t try AsyncTask right away is that I thought it was well-suited for tracking progress of a background task but not for what I wanted: computing moves that need to be displayed on the screen. Once I saw that the publishProgress method could be used to send any kind of object you want, I realized that it could handle passing moves in a game from the background task to the UI.
My doInBackground method has the following loop in it:
// Loop until cancelled or the max moves number is exceeded.
while (!done) {
...
// Use the progress int values to report which player moved
// and what the move was.
publishProgress (player, nextMove);
...
} // end while
...
To be able to cancel the background task, you have to make calls to isCancelled in the loop. My example does this at the top of the loop.
if (isCancelled ()) break;
Back on the UI thread, you have to call the cancel method. I did this when the Stop button was clicked.
cancel (true);
Another thing to remember is that your activity can be paused at any time. For most apps, that means you should stop your background task. Check method onDestroy in the example and you will find call to stop the background task and cleanup.
endBackgroundTasks (true);
That method checks to see if a background task is running and cancels it if it is.
My initial version of this example had the app canceling the background task whenever onPause and onStop were called. Those are called whenever there is a change in orientation. After reading “Handling Progress Dialogs and Orientation Changes” (see references and comments below), I changed this example to keep the background task running as the orientation changes and even when you click the home button and start another app. When you return to this app, you see that the background task is still running or that it completed while you were away.
Accidentally Non-Responsive
One little mistake I made while testing turned out to be a good thing. Instead of starting the background task correctly with
t.execute (1, 2);
I mistakenly used the doInBackground method directly.
t.doInBackground (1, 2);
This error helped me see what a non-responsive app looks like. Starting with doInBackground means the background task is not being set up at all. So the long computation starts — in the UI thread — and nothing changes on the screen and the buttons cease to work until the 1000 or so iterations finishes.
References
Handling Progress Dialogs and Orientation Changes
This is an excellent tutorial on AsyncTask. I suggest that you read it thoroughly. Section 5 was especially useful to me when I reworked my example to handle orientation changes.
Source Code
The source code for this demo application is available in two places: (1) download from Wglxy.com. (2) download from Google Docs. If you find that the app does not build in Eclipse, be sure to do a clean build by using the “Clean” item on the Project menu.
This example app has been tested with the Android emulator and on an LG Optimus phone. The Android version is 2.2.


does this code handle orientation changes
No. That’s something I still need to understand.
I had a similar problem. The problem arises because the asynctask has a reference to the activity that creates it. When the orientation changes the activity is destroyed and recreated. The asynctask still has a reference to the old activity and tries to update it.
have a look here.
http://blog.doityourselfandroid.com/2010/11/14/handling-progress-dialogs-and-screen-orientation-changes/
Thanks. That’s going to be a very useful reference.
I had read some about the problem with the background task holding on to the activity, but I have not done enough there yet. My example has code in the activity to cancel the background task, and it removes the reference from the activity to the task. What I did not do was remove the reference from the task to the activity or arrange for the task to stop sending updates.
As noted above in the modified post, your note was very useful. Thanks.
It very useful , good practice for AsynTas Example
AsyncTask Android example with ProgressBar