1. What is AsyncTask?
AsyncTask is an abstract class provided by Android which helps us to use the UI thread properly. This class allows us to perform long/background operations and show its result on the UI thread without having to manipulate threads.
The AsyncTask Android class lets us sort of bind background tasks to the UI thread. So using this class, you can perform background operations and then publish the results to the UI thread that updates the UI components. This way you won’t have to deal with threads, handlers, runnables, etc. directly yourself. It’s sort of a helper class around Thread
and Handler
.
2. When to use AsyncTask?
Well, any long running operation that may block the main thread and make the app unresponsive could be done via AsyncTask. Like downloading multiple files, or making HTTP requests to your server, decoding images, etc. According to the
According to the documentation, AsyncTask should ideally be used for short background operations that lasts for a few seconds at most. For longer tasks, the Executor framework from the java.util.concurrent
package should be used that contains classes/interfaces likeExecutor
, ThreadPoolExecutor
and FutureTask
.
3. How to Create and Implement
In order to use AsyncTask, you’ll have to subclass it. This is the simplest form of implementation of an AsyncTask:
1 2 3 4 5 6 7 8 9 10 |
// AsyncTask class MyAsyncTask extends AsyncTask { @Override protected Object doInBackground(Object... params) { // Do some background work Log.d(TAG, "MyAsyncTask@doInBackground from another thread"); return new Object(); } } |
To execute the task you’ll have to instantiate it and call execute():
1 |
new MyAsyncTask().execute(); |
The execute()
method can be called only once per AsyncTask instance, that means AsyncTask can be executed only once – just like a Thread
.
The example that we just saw is the most basic form of an AsyncTask implementation. Let’s now see all the important methods that you can override in a full-blown implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
class MyAsyncTask extends AsyncTask<Params, Progress, Result> { @Override protected void onPreExecute() { // Runs on the UI thread before doInBackground() } @Override protected Result doInBackground(Params... params) { // Perform an operation on a background thread } @Override protected void onProgressUpdate(Progress... values) { // Runs on UI thread after publishProgress(Progress...) is invoked // from doInBackground() } @Override protected void onPostExecute(Result result) { // Runs on the UI thread after doInBackground() } @Override protected void onCancelled(Result result) { // Runs on UI thread after cancel() is invoked // and doInBackground() has finished/returned } } |
- doInBackground: Code performing long running operation goes in this method. When onClick method is executed on click of button, it calls execute method which accepts parameters and automatically calls doInBackground method with the parameters passed.
- onPostExecute: This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.
- onPreExecute: This method is called before doInBackground method is called.
- onProgressUpdate: This method is invoked by calling publishProgress anytime from doInBackground call this method.
- onCancelled: Runs on UI thread after cancel() is invoked and doInBackground() has finished/returned.
Note: As you can see all callbacks except the
doInBackground()
method are executed on the UI thread.
It is very important to understand the three AsyncTask generic types:
- Params – Type of data passed to the task upon execution, i.e., arguments passed to
execute()
and accepted bydoInBackground()
. - Progress – Type of progress data reported by the background thread, i.e., from
doInbackground()
to the UI thread inonProgressUpdate()
. - Result – Type of result returned/produced by the background thread (
doInBackground()
) and sent to the UI thread (onPostExecute()
).
The 3 dots argument is referred to as varargs (arbitrary number of arguments).
An AsyncTask can be in one of the following states:
- PENDING – AsyncTask has been instantiated but
execute()
hansn’t been called on the instance. - RUNNING –
execute()
has been called. - FINISHED – The execution has been done as well as
onPostExecute()
oronCancelled()
has been called.
execute(Runnable): The AsyncTask class has another version of its execute()
method which is static and accepts a Runnable. It is just a convenience version of the other execute()
(that we’ve seen before) for use with simple Runnable objects.
4. Threading rules:
AsyncTask
instances can only be used one time. Instead, just call your task like
1 |
new MyAsyncTask().execute(""); |
From the AsyncTask API docs:
There are a few threading rules that must be followed for this class to work properly:
- The task instance must be created on the UI thread.
- execute(Params…) must be invoked on the UI thread.
- Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params…), onProgressUpdate(Progress…) manually.
- The task can be executed only once (an exception will be thrown if a second execution is attempted.)