BLOGS

Product Engineering Outsourcing, Tech Talk

15
Jul

Android Async Task

This blog post introduces one of the important mechanism of Async Task for Android with sample code.

Android implements single thread model and whenever an Android application is launched, a thread is created. Now assume you have long running operations like a network call on a button click in your application. On button click a request would be made to the server and response will be awaited. Now due to the single thread model of Android, till the time response is awaited your UI screen hangs or in other words, it is non-responsive.

We can overcome this by creating a new Thread and implement the run method to perform the time consuming operation, so that the UI remains responsive.

As shown below a new Thread is created in onClick method

public void onClick(View v) {
    Thread t = new Thread(){
    public void run(){
	// Long running operation
	  }
   };
   t.start();
}

But since Android follows single thread model and Android UI toolkit is not thread safe, so if there is a need to make some change to the UI based on the result of the operation performed, then this approach may lead some issues.

There are various approaches via which control can be given back to UI thread (Main thread running the application). Handler approach is one among the various approaches.

Handler

Let us look at the code snippet below to understand Handler approach.

public void onClick(View v) {
   Thread t = new Thread(){
	public void run(){
   	   // Long time comsuming operation
	 	Message myMessage=new Message();
		Bundle resBundle = new Bundle();
		resBundle.putString("status", "SUCCESS");
		myMessage.obj=resBundle;
		handler.sendMessage(myMessage);
	}
  };
  t.start();
}

As seen we have modified the original run method and added code to create Message object, which is then passed as parameter to sendMessage method of Handler. Now let us look at the Handler. Note that the code below is present in the main activity code.

private Handler handler = new Handler() {
@Override
	public void handleMessage(Message msg) {
		// Code to process the response and update UI.
	}
};

After the execution of long running operation, the result is set in Message and passed to sendMessage of handler. Handle will extract the response from Message and will process and accordingly update the UI. Since Handler is part of main activity, UI thread will be responsible for updating the UI.

Handler approach works fine, but with increasing number of long operations, Thread needs to be created,  run method needs to be implemented and Handler needs to be created. This can be a bit cumbersome. The Android framework has identified this pattern and has nicely enveloped it into what is called an Android Async Task. Let us look at how it can help simplify things.

Async Task

Android Async Task takes cares of thread management and is the recommended mechanism for performing long running operations.

Let us look at a sample class LongOperation, which extends the AsyncTask below:

private class LongOperation extends AsyncTask<String, Void, String> {

	@Override
	protected String doInBackground(String... params) {
		// perform long running operation operation
		return null;
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
	 */
	@Override
	protected void onPostExecute(String result) {
		// execution of result of Long time consuming operation
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onPreExecute()
	 */
	@Override
	protected void onPreExecute() {
	// Things to be done before execution of long running operation. For example showing ProgessDialog
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onProgressUpdate(Progress[])
	 */
	@Override
	protected void onProgressUpdate(Void... values) {
      // Things to be done while execution of long running operation is in progress. For example updating ProgessDialog
	 }
}

Modify the onClick method as shown below:

public void onClick(View v) {
new LongOperation().execute("");
}

As seen class LongOperation extends AsyncTask and implements 4 methods:

  1. 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.
  2. onPostExecute: This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.
  3. onPreExecute: This method is called before doInBackground method is called.
  4. onProgressUpdate: This method is invoked by calling publishProgress anytime from doInBackground call this method.

Overriding onPostExecute, onPreExecute and onProgressUpdate is optional.

Points to remember:

  1. Instance of Async Task needs to be created in UI thread. As shown in onClick method a new instance of LongOperation is created there. Also execute method with parameters should be called from UI thread.
  2. Methods onPostExecute, onPreExecute and onProgressUpdate should not be explicitly called.
  3. Task can be executed only once.

Hope this blog helped you understand Android async task and why it is important in Android application development.

Prashant Thakkar

Xoriant Mobile Center of Excellence.

12 comments on “Android Async Task
  1. praveen says:

    Thank you a lot Prashant. It is very useful.

  2. Fredrik says:

    Great, worked like a charm! :)

  3. Lonnie VanZandt says:

    Prashant, this pattern appears adequate for run-to-completion asynchronous operations. What is the recommended Android pattern for asynchronous operations which periodically or sporadically repeat?

    For example, what is the recommended approach for a background job (not wanting to lead an answer by using “task” or “service”) which wakes up, checks query parameters, prepares a web service query, executes the query, marshals query results, posts a notification to observers, and goes to sleep for some short while. When it awakes, it repeats the “job”. It does this over and over until instructed to cancel itself.

  4. Tilsan says:

    This is a Nice Article. Keep up ur good Work !!!!!!!!!!

  5. Prashant Thakkar Prashant Thakkar says:

    Hi Lonnie,

    As per my understanding for the kind of tasks (Job) that you want to perform, writing a service would be an better approach. Service runs in the background for indefinite period of time and it is possible to control and access the service via the exposed interface.

  6. Yadavendra says:

    Thanks a lot .This is very helpful

  7. Matze says:

    Hey Prashant,
    does “Task can be executed only once” mean it can only be executed once and than again if the task has finished or it can not be executed ever again? =)
    Might sound a little weird but I don’t need to call it serveral times over and over again, so it should be executed before I call it again.

  8. Matze says:

    Oh, thx for your tutorial by the way, it’s really good =)

  9. Ron says:

    Hi very useful BUT..
    where you have called new LongOperation().execute(“”) I am calling new CameraTask().execute() and getting an error ‘cannot be resolved to a type’. I have the Async import at the top of the file. I also received an error re ‘private class CameraTask extends AsyncTask’ in that only abstract or final are permitted. I am hoping someone can shed some light on this.
    Thanks

  10. Ron says:

    hi found misplaced } which fixed it!

  11. Vijay says:

    Hi, thanks for the good tutorial. How do we get back the result to the calling UI thread.

  12. Prashant Thakkar Prashant Thakkar says:

    AsyncTask is either written as anonymous inner classes i.e. within the method or as a private inner class in the same class file. So UI component to be modified can be accessed by declaring the it as global variable.

    Example:
    private void doSomething() {
    new AsyncTask<String, Void, String>(){
    @Override
    protected void onPostExecute(String result) {
    if (result != null && result.trim().length() == 0){
    textView.setText(result);
    }else{
    textView.setText("Empty Input Parameter");
    }
    }
    @Override
    protected String doInBackground(String… param){
    return param;
    }
    }.execute("value1");
    }

    Thanks
    Prashant Thakkar

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>