Threading in Android part 2: Async Tasks
In the previous post we saw one way to deal with threads in Android, which is by using Handlers. In this post we'll see how to use another technique which is using AsyncTask class.
AsyncTask is an abstract class that provides several methods managing the interaction between the UI thread and the background thread. it's implementation is by creating a sub class that extends AsyncTask and implementing the different protected methods it provides.
Let's demonstrate how to user AsyncTask by creating a simple activity that has two buttons and a progress bar:
Here we have two buttons: one to start progress and the other to stop it.AsyncTask is an abstract class that provides several methods managing the interaction between the UI thread and the background thread. it's implementation is by creating a sub class that extends AsyncTask and implementing the different protected methods it provides.
Let's demonstrate how to user AsyncTask by creating a simple activity that has two buttons and a progress bar:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="@+id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Show Progress"
></Button>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/progress"
style="?android:attr/progressBarStyleHorizontal"
></ProgressBar>
<Button
android:id="@+id/btnCancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Cancel"
></Button>
</LinearLayout>
Creating the AsyncTask sub class:
class ProgressTask extends AsyncTask<Params, Progress, Result>{The AsyncTask declaration has three Varargs parameters which are:
}
- Params: parameter info passed to be used by the AsyncTask.
- Progress: the type of progress that the task accomplishes.
- The result returned after the AsyncTask finishes.
In our example our class will be like this:
class ProgressTask extends AsyncTask<Integer, Integer, Void>{
}
The parameter and the progress are of type Integer and the result is Void as our tasks does not return anthing (returns null).
The second step is overriding the protected methods defined by the AsyncTask class that handle the execution life cycle of the AsyncTask.
We have five methods to implement which are:
- onPreExecute: the first method called in the AsyncTask, called on the UI thread.
- doInBackground: the method that executes the time consuming tasks and publish the task progress, executed in background thread.
- onProgressUpdate: method that updates the progress of the AsyncTask, run on the UI thread.
- onPostExecute: the final method that gets called after doInBackground finishes, here we can update the UI with the results of the AsyncTask.
- onCancelled: gets called if the AsyncTask.cancel() methods is called, terminating the execution of the AsyncTask.
ProgressTask task=new ProgressTask();Implementing the AsyncTask:
// start progress bar with initial progress 10
task.execute(10);
class ProgressTask extends AsyncTask<Integer, Integer, Void>{
@Override
protected void onPreExecute() {
// initialize the progress bar
// set maximum progress to 100.
progress.setMax(100);
}
@Override
protected void onCancelled() {
// stop the progress
progress.setMax(0);
}
@Override
protected Void doInBackground(Integer... params) {
// get the initial starting value
int start=params[0];
// increment the progress
for(int i=start;i<=100;i+=5){
try {
boolean cancelled=isCancelled();
//if async task is not cancelled, update the progress
if(!cancelled){
publishProgress(i);
SystemClock.sleep(1000);
}
} catch (Exception e) {
Log.e("Error", e.toString());
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// increment progress bar by progress value
progress.setProgress(values[0]);
}
@Override
protected void onPostExecute(Void result) {
// async task finished
Log.v("Progress", "Finished");
}
}
Here are the steps:
- onPreExecute() method first gets called initializing the maximum value of the progress bar.
- doInBackground(Integer... params) methods gets called by obtaining the initial start value of the progress bar then incrementing the value of the progress bar every second and publishing the progress as long as the async task is not cancelled.
- onProgressUpdate(Integer... values) method is called each time progress is published from doInBackground, thus incrementing the progress bar.
- onPostExecute(Void result) is called after doInBackground finished execution.
- void onCancelled() is called if task.cancel(true) is called from the UI thread. it may interrupt the execution preventing onPostExecute from being executed.
@Override
public void onClick(View v) {
ProgressTask task=new ProgressTask();
switch(v.getId()){
case R.id.btn:
task.execute(10);
break;
case R.id.btnCancel:
task.cancel(true);
break;
}
}
No comments: