The AsyncTask class lets you put the heavy work in the background. It lets the user know when the work is finished.
The AsyncTask can also let the user know how the work is progressing.
The AsyncTask takes care of all the thread creation, management, and synchronization with the main thread. You don’t have to worry about it.
AsyncTasks are short
AsyncTasks are great for quick (a few seconds) background processing where you need to show the progress to the user.
Use a Service if your background process will last longer that a few seconds.
AsyncTasks can only be executed once
You start the AsyncTask by creating a new instance of it and then calling execute().
You can only call execute() once else you’ll get an error.
Our AsyncTask tutorial app
Running the app displays a progress bar and a button. Pressing the button starts an AsyncTask which downloads an image. The progress bar indicates the progress.
When the AsyncTask is finished, it displays the image and removes the progress bar.
Press the button to start the AsyncTask. It shows the progress of the download in a progress bar. When the download is finished, the progress bar is removed and the image displayed
Creating the AsyncTask
Our AsyncTask is an inner class.
Create an AsyncTask subclass by extending AsyncTask:
Our AsyncTask subclass
The AsyncTask types
The AsyncTask uses three types:
Our AsyncTask types
AsyncTask<Params, Progress, Result>
The AsyncTask types: what they are?
- Params – the type of parameters sent to the task
- Progress – the type of progress units – used to show progress
- Result – the type of the result of the background operation
Any or all of these can be Void.
The AsyncTask methods
The AsyncTask has 4 possible methods:
- onPreExecute() – optional. Runs on the main thread. Used to set up the task. We set up the progress bar here
- doInBackground(Params…) – does the work on a background thread. The parameters are passed here when execute() is called. Returns the result and can also publish units of progress
- opProgressUpdate(Progress…) – optional. Runs on the main thread. Called by publishProgress(Progress…) in doInBackground(Params…). We use it to update our progress bar
- onPostExecute(Result) – optional. Runs on the main thread. It receives the result of the background operation. We use it to display the image
Here’s our onPreExecute() method:
We set up the progress bar in onPreExecute(). It’s on the main thread
Note the following:
- we get a reference to the progress bar in the layout file
- PROGRESS_BAR_MAX – we set the maximum value for the progress bar here. Progress updates will continue to increase the colored bar as the file downloads. Once the download is finished, the progress value will have reached the maximum set here
Now for the part that does the work
Here’s the code for our doInBackground(Params…) method:
The first part of the doInBackground() method
This is the first part of the method. Note the following:
- params – this is the URL of the image as passed in the execute() method. You could pass a number of URL’s so your execute could look like this: execute(url1, url2, url3)
- path – we’re going to download a file and save it. This is the path to the file that we will save
- connection – we create a new internet connection object which we’ll use to download the file
- try – we put the connection, download and saving of the file within a try/catch/finally statement to take care of any problems without crashing the app
- url – we get the first URL out of params (even though there is only one)
- openConnection() – connects to the given url
Showing a progress dialog
You can use a progress dialog instead of a progress bar to show the status of the download.
Bear in mind that the dialog displays on the main thread. The user will have to wait for it to dismiss before being able to interact with the app.
You can use a Progress Dialog if you wish but it runs on the main thread
To show the dialog, include this code in the onPrexecute() method (and remove the progress bar code):
Use this code to display a progress dialog
To dismiss the dialog when the download is finished. Include this code in the onPostExecute() method:
Use this code to dismiss the progress dialog
We’re using the progress bar
Continuing with the doInBackground() method.
We’ve included a progress bar in the layout file. We want the colored bar to increase as the download progresses. Here’s one way of doing that:
One way of getting a value to show the status of the download
Without going into detail, we get the size of the file and calculate a value for each increment in the download.
These incremental values are passed on to the onProgressUpdate(Integer…progress) method by calling publishProgress(i):
This method receives incremental values as the download proceeds. These values are used to set the position of the progress bar
This sets the progress bar to the new value (and the colored bar moves closer to the maximum).
Continuing with the doInBackground() method.
Here’s the remainder of the code:
The remainder of the doInBackground() code
We read the file from the url and save it on the device. The catch statement takes care of any errors. We close the connection in the finally statement.
Once the download is finished, we set the progress bar to its maximum and return the path to the saved file. onPostExecute() is called.
Knock-off time: the work’s done so we notify the main thread
Here’s the code for the onPostExecute() method:
This runs on the main thread and updates the User Interface
This runs on the main thread. It receives the path to the saved file from the doInBackground() method once the work is finished.
Note the following:
- we no longer need the progress bar so we make it invisible
- we get the image by decoding the saved bitmap file
- we display the image in the image view
It all started with a button press
We’re using the AsyncTask to download an image. Here’s the URL:
The URL of the image that we want to download
Pressing the button starts the AsyncTask. Here’s the button code:
Pressing the button starts the download in an AsyncTask
We create a new instance of our AsyncTask and then call execute(). We pass the image URL as a parameter.
The AsyncTask will take care of the rest, downloading the file, notifying the user of the progress and eventually displaying the image.
Here's a great AsyncTask video tutorial that I'm sure you will find helpful.
Note that the AsyncTask is not bound to the activity in which it was created. The AsyncTask will run until it has completed it's task. On the other hand, the activity may die before the AsyncTask has completed it's task. The AsyncTask will then try to update the UI of the original activity (if required) and may throw an exception because the activity no longer exists. You need to be aware of this and construct your code accordingly.
I hope that you have found this tutorial helpful.
This tutorial was created using Android Studio. You can download the project files here
Are you using Eclipse or another IDE? Here's how you can use this project's Android Studio files.