Android AsyncTasks, for updating your UI

March 11, 2012

Last time, I talked about how to use Android Handlers for handling a blocking task in the background.  While Handlers are very powerful, they can easily get too complicated for larger tasks.

This time, let’s take a look at the Android AsyncTasks.

AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

The AsyncTask class takes care of all of the hard work for us!  Because the AsyncTask runs in a “worker thread” as part of the UI Thread, you are not guaranteed that it is running in a multi-threaded model.  Instead, it is executed in an asynchronous way.

Knowing how your application lifecycle impacts your user interface plays a big role here.  Typically, using an AsyncTask is appropriate because your application is likely the only foreground Activity.

While the details of this post rely on using an asynchronous model, I’m not going to cover the details of process/thread models.  Instead, I recommend taking at look at this introduction to asynchronous programming.  The author, Dave Peticolas, has some great graphics to illustrate the differences between those models – single-threaded, multi-threaded, and asynchronous. (Thanks @_swanson for sharing this!)

So, what does it look like?

An AsyncTask is actually really easy to implement.  The AsyncTask goes through 4 steps

  • onPreExecute() – called immediately after the task is executed, used for setup
  • doInBackground(Params…) –  used for long-running tasks
  • onProgressUpdate(Progress…) – used to display progress to the user, for example “On step X out of Y”
  • onPostExecute(Result) – called immediately after the task is finished

The interesting steps are “doInBackground” and “onPostExecute”.  Below is an example that covers both of these.

privateclass MyAsyncTask extends AsyncTask<[String](https://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string), [Void](https://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+void), String>{ @Override protected[String](https://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string) doInBackground([String](https://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string)… params){ // this is where you implement your long-running task return doSomeLongOperation(); }

@Override
publicvoid onPostExecute(String result){
// here, you can update, and manipulate, your views
updateUiWithResult(result);
}
}

That’s all it takes to implement your AsyncTask.  Simple, right?

The beautiful part about AsyncTasks is, the “onPostExecute()” method is able to update your view.  This is powerful because you don’t have to worry about some of the issues we talked about with Handlers, where the view elements might return a Null Pointer Exception.

The 3 generic types that are used by the AsyncTask make it very flexible, as well.

So, how do I use it?

Using the AsyncTask, is even easier than implementing one.  All you do is call “execute()” on your task.

MyAsyncTask().execute();

You don’t have to make any calls to the 4 steps mentioned above…calling “execute()” will do all of that for you.

I recommend waiting to execute your task until your view has been loaded.  That means, normally you can execute that task as early as in your “onResume()” callback.

However, you may have other dependencies, like a database connection or a service connection, that require you to wait until that connection is established.  In those cases, I recommend using a BroadcastReceiver and executing your task once that receiver is called.

If you find yourself struggling with finding the right time to execute your task, or perhaps you have multiple tasks getting chained together, or maybe you have implemented some handlers to execute tasks (or vice versa), you should consider looking at one of the many Android Service types.  I will cover services in the next post.

Android Thread Series:

  1. Overview
  2. Handlers
  3. AsyncTasks
  4. Services and Messengers
  5. Conclusion