The first Android-specific concurrency construct we'll look at is android.os.AsyncTask
, a neat construct that encapsulates the messy business of managing threads, performing background work, and publishing progress and results back to the main thread to update the user interface.
In this chapter we will cover the following topics:
AsyncTask
AsyncTask
typesAsyncTask
issuesAsyncTask
AsyncTask
was introduced in Android at API level 3, Cupcake, with the express purpose of helping developers to avoid blocking the main thread. The Async
part of the name of this class comes from the word asynchronous, which literally means not occurring at the same time.
AsyncTask
is an abstract class, and as such, must be subclassed for use. At the minimum, our subclass must provide an implementation for the abstract doInBackground
method, which defines the work that we want to get done off the main thread.
protected Result doInBackground(Params… params)
There are four other methods of AsyncTask
which we may choose to override:
protected void onPreExecute() protected void onProgressUpdate(Progress… values) protected void onPostExecute(Result result) protected void onCancelled(Result result)
Although we will override one or more of these five methods, we will not invoke them directly from our own code. These are callback methods, meaning that they will be invoked for us (called back) at the appropriate time.
The key difference between doInBackground
and the other four methods is the thread on which they execute.
Before any background work begins, onPreExecute
will be invoked and will run to completion on the main thread.
Once onPreExecute
completes, doInBackground
will be scheduled and will start work on a background thread.
During the background work, we can publish progress updates from doInBackground
, which trigger the main thread to execute onProgressUpdate
with the progress values we provide. By invoking this on the main thread, AsyncTask
makes it easy for us to update the user interface to show progress (remember that we can only update the user interface from the main thread).
When the background work completes successfully, doInBackground
may return a result. This result is passed to onPostExecute
, which is invoked for us on the main thread so that we can update the user interface with the results of our background processing.
This pattern of passing data from one thread to another is very important, because it helps us to avoid several thread-safety issues.
Our AsyncTask
could manipulate fields of the enclosing Activity
class, but then we would have to take extra precautions, such as adding synchronization to prevent race conditions and ensure visibility of updates.
The preceding figure displays a sequence of method calls executed by AsyncTask
, illustrating which methods run on the main thread versus the AsyncTask
background thread.
If we invoke AsyncTask's cancel
method before doInBackground
completes, onPostExecute
will not be called. Instead, the alternative onCancelled
callback method is invoked so that we can implement different behavior for a successful versus cancelled completion.
18.226.28.192