<p>This article discusses the threading model used by Android applications and how applications can ensure best UI performance by spawning worker threads to handle long-running operations, rather than handling them in the main thread. The article also explains the API that your application can use to interact with Android UI toolkit components running on the main thread and spawn managed worker threads. </p>
<h3>The UI thread</h3>
<p>When an application is launched, the system creates a thread called
"main" for the application. The main thread, also called the <em>UI
thread</em>, is very important because it is in charge of dispatching the
events to the appropriate widgets, including drawing events.
It is also the thread where your application interacts with running
components of the Android UI toolkit. </p>
<p>For instance, if you touch the a button on screen, the UI thread dispatches
the touch event to the widget, which in turn sets its pressed state and
posts an invalidate request to the event queue. The UI thread dequeues
the request and notifies the widget to redraw itself.</p>
<p>This single-thread model can yield poor performance unless your application
is implemented properly. Specifically, if everything is happening in a single
thread, performing long operations such as network access or database
queries on the UI thread will block the whole user interface. No event
can be dispatched, including drawing events, while the long operation
is underway. From the user's perspective, the application appears hung.
Even worse, if the UI thread is blocked for more than a few seconds
(about 5 seconds currently) the user is presented with the infamous "<a href="http://developer.android.com/guide/practices/design/responsiveness.html">application not responding</a>" (ANR) dialog.</p>
<p>If you want to see how bad this can look, write a simple application
with a button that invokes <code>Thread.sleep(2000)</code> in its
AsyncTask documentation</a> for a full understanding on how to use this class,
but here is a quick overview of how it works:</p>
<ul>
<li>You can specify the type, using generics, of the parameters, the progress values and the final value of the task</li>
<li>The method <a href="http://developer.android.com/reference/android/os/AsyncTask.html#doInBackground%28Params...%29">doInBackground()</a> executes automatically on a worker thread</li>
<li><a href="http://developer.android.com/reference/android/os/AsyncTask.html#onPreExecute%28%29">onPreExecute()</a>, <a href="http://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute%28Result%29">onPostExecute()</a> and <a href="http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate%28Progress...%29">onProgressUpdate()</a> are all invoked on the UI thread</li>
<li>The value returned by <a href="http://developer.android.com/reference/android/os/AsyncTask.html#doInBackground%28Params...%29">doInBackground()</a> is sent to <a href="http://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute%28Result%29">onPostExecute()</a></li>
<li>You can call <a href="http://developer.android.com/reference/android/os/AsyncTask.html#publishProgress%28Progress...%29">publishProgress()</a> at anytime in <a href="http://developer.android.com/reference/android/os/AsyncTask.html#doInBackground%28Params...%29">doInBackground()</a> to execute <a href="http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate%28Progress...%29">onProgressUpdate()</a> on the UI thread</li><li>You can cancel the task at any time, from any thread</li>
</ul>
<p>In addition to the official documentation, you can read several complex examples in the source code of Shelves (<a href="http://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/activity/ShelvesActivity.java">ShelvesActivity.java</a> and <a href="http://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/activity/AddBookActivity.java">AddBookActivity.java</a>) and Photostream (<a href="http://code.google.com/p/apps-for-android/source/browse/trunk/Photostream/src/com/google/android/photostream/LoginActivity.java">LoginActivity.java</a>, <a href="http://code.google.com/p/apps-for-android/source/browse/trunk/Photostream/src/com/google/android/photostream/PhotostreamActivity.java">PhotostreamActivity.java</a> and <a href="http://code.google.com/p/apps-for-android/source/browse/trunk/Photostream/src/com/google/android/photostream/ViewPhotoActivity.java">ViewPhotoActivity.java</a>). We highly recommend reading the source code of <a href="http://code.google.com/p/shelves/">Shelves</a> to see how to persist tasks across configuration changes and how to cancel them properly when the activity is destroyed.</p>
<p>Regardless of whether or not you use <a href="http://developer.android.com/reference/android/os/AsyncTask.html">AsyncTask</a>,
always remember these two rules about the single thread model: </p>
<ol>
<li>Do not block the UI thread, and
<li>Make sure that you access the Android UI toolkit <em>only</em> on the UI thread.
</ol>
<p><code>AsyncTask</code> just makes it easier to do both of these things.</p>