One Way to Cancel an AsyncTask

The AsyncTask class in Android provides an easy way to do a task in the background, without adversely impacting the main user interface thread. Generally speaking, it works really well for me. For a working example, refer to “Using Android AsyncTask For Background Tasks“. Recently, however, I have had a problem in cancelling the task.

Here’s my situation. I am working on a game. Part of the game involves a background task that computes moves for two players. As moves are computed, they are shown on the app’s screen by making calls to publishProgress. The calls occur in a loop.

while (gameNotOver) {
  publishProgress (player, move);

Back in the activity that starts the AsyncTask, I have a call to cancel the task: “t.cancel (true)”. To break out of the loop, I added calls to isCancelled.

if (isCancelled ()) break;

The problem arises because the UI thread’s call to cancel does not actually stop the task. It simply sets a flag in the AsyncTask and then arranges for a call to onCancelled. You certainly can do things in onCancelled that touch the user interface. That’s how AsyncTask was designed. However, the timing is a bit off. The cancel request is received very quickly, but in my case the background task keeps going until it checks with “isCancelled ()” and breaks out of the loop. That creates uncertainty in the activity running on the UI thread. Is the background task really stopped, or is it about to stop?

In my app, the call to cancel the background task is being made not to stop the game completely, but rather to pause the game so the user can look around. The UI has a Play and a Pause button, with cancel tied to the Pause button. When the user is done looking around, he or she selects the Play button to resume the game. That’s what the user thinks is happening. Behind the scenes, the code in the activity picks up the object that holds the state of the game and starts a new AsyncTask to continue from that state.

I do not want to have more than one active AsyncTask altering the game state. As described above, I found that onCancelled gets called immediately, but the real background task can take a bit longer to break out of the loop. To address this problem, I changed the way I used publishProgress in the background task. I added an extra argument to indicate the kind of progress information that was being sent. Inside the loop, I send “move” progress information and outside the loop I send “cancel” progress information if indeed the task was cancelled. It looks like the following code:

while (gameNotOver) {
  if (isCancelled () break;
  publishProgress (KIND_move, player, move);
if (isCancelled ()) {
  publishProgress (KIND_cancel, -1, -1);
return moveCount;

I don’t know if this is an ideal solution, but it does get the job done and works using the protocol defined by AsyncTask. The only thing that is a bit unconventional is the use of several integer arguments to report progress to the UI thread. Most examples I have seen use the arguments to report progress in terms of percent completed.


About Bill Lahti

Bill Lahti is a software engineer building mobile applications and knowledge management solutions. Two of his interests are writing for this blog and building Android apps, with strategy games being an area of particular interest.
This entry was posted in Android and tagged , , , . Bookmark the permalink.

2 Responses to One Way to Cancel an AsyncTask

  1. Carlos Sessa says:

    Thanks for the post. It calls my attention you are using an AsyncTask for the game loop. Doesn’t make a lot of sense 😦

    Why don’t you take a look at the available game frameworks for android:


    • blahti says:

      I am very new to game development and still learning. So those references are very helpful. Thanks for calling them to my attention.

      I hope the example I used does not obscure the fact that there is a little problem with AsyncTask. Whatever the nature of the background task, the lag between the cancel request being received and the background task actually stopping is something that might cause problems.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.