Example of AsyncTask and user notification in Android

When executing long and tedious tasks within an Android app, it is important to:

  • maintain the UI active
  • keep the user informed of progress made

Otherwise it might appear as if the app has crashed!

So what needs to be done is to create a thread in which the tedious and long task will execute, while still keeping the UI thread lively and active.
One simple way of providing this feature on Android is to use an AsyncTask. AsyncTask creates another thread in which your task will execute, while still retaining hold of the UI to be able to show progress.

In this example, we will call an AsyncTask from the Activity, execute some steps, update a progress dialog after each step, and output a final string in one TextView of the Activity.

One thing to point out is that an AsyncTask must be subclassed to be used. So declare it within your Activity class.

        //the three arguments of AsyncTask are:
        //params: type of parameters sent to the task to execute (here, nothing)
        //progress: type of data used to show progress (here, a string)
        //result: type of data for the result of the background operation (here, a string)
	private class MyAsyncTask extends AsyncTask {
	    /** progress dialog to show user that the backup is processing. */
	    private ProgressDialog dialog;
	    /** The activity launching this thread */
	    private AsyncTaskDemo activity;

Now to define the AsyncTask constructor; in our example, we pass the launching Activity as argument to handle notifications, and define the progress dialog attached to the UI thread:

	    public MyAsyncTask(AsyncTaskDemo  activity) {
	        this.activity = activity;
	        dialog = new ProgressDialog(this.activity);
	    }

The first method to execute after the creation of the background task is actually in the UI thread, and is onPreExecute; we use it to start the progress dialog:

            //runs on the UI thread
	    protected void onPreExecute() {
                //launch the progress dialog on the UI thread;
                //it will run until we tell it to stop
		this.dialog.setMessage("Starting execution...");
		this.dialog.show();
	    }
	 }

The main task to execute runs in the newly created thread, in the background; it uses the arguments passed when the task was created in the Activity. This particular creates a String variable that will be modified during the execution of various steps, and returned at the end.

            //the main task to execute;
            //this executes in the new thread
	    protected String doInBackground(Void... args) {
	    	String result = "";
                ExecuteFirstStep();
	    	publishProgress("ExecuteFirstStep done!");
                result += "1\n";
                ExecuteSecondStep();
	    	publishProgress("ExecuteSecondStep done!");
                result += "2\n";
                ExecuteThirdStep();
	    	publishProgress("ExecuteThirdStep done!");
                result += "3\n";
                //
                //insert as many steps as you need!!!
                //
                ExecuteLastStep();
                publishProgress("ExecuteLastStep done!");
                result += "n\n";
                result +="All steps executed!"
                return result;
            }

When publishProgress() calls complete in the background thread, onProgressUpdate is automatically called in the UI thread; in this example, it is used to update the text of the progress dialog:

            //this method is used to publish progress; it is
            //called automatically after each call to publishProgress()
            //runs on the UI thread
	    protected void onProgressUpdate(String... progress) {
                //you need to cast the params to the type you want!
	    	String tmpStr = (String)progress[0];
                //now update the progress dialog
	    	dialog.setMessage(tmpStr);
	    }

Finally, after doInBackground() completes, onPostExecute() is called to clean up; the String returned by doInBackground is used as argument, and is passed to modify a TextView of the Activity.

	    //runs on the UI thread
	    protected void onPostExecute(String result) {
                 textViewFromActivity.setText(result);
	         if (dialog.isShowing()) {
	             dialog.dismiss();
	         }
	    }

That’s your AsyncTask defined!
This task can be launched in just one line from your Activity:

        new MyAsyncTask(this).execute();

You can declare as many AsyncTasks as you need in the same activity, with different tasks being executed with different kind of parameters, and different kinds of outputs.

Comments (and code reviews!) are welcome!

One Response to “Example of AsyncTask and user notification in Android”

  1. Rob says:

    Thanks for the tutorial. I was looking for a way to use strings to publish my progress, and this was helpful.

    I do have a couple suggestions that might improve it a bit though:
    1) If you copy and paste the code into Eclipse, there are some kind of characters at the beginning of each line that cause it (at least on Linux) to make errors due to them.
    2) It would be really nice to see the whole Activity java file as a unit. For example, AsyncTaskDemo is not defined in the code you have here, and for some of us who are rather new to Java and are using pattern matching techniques to see what needs to go where, it would help.

    Thanks for the help!

    Rob

Leave a Reply