Through this article we will look at one of the important feature of Android i.e AsyncTask for performing task which takes long time for execution with example. Also we will look at other mechanisms and see why AsyncTask is better approach.

Android application follows single thread model i.e. when android application is launched, a thread is created for running that application. This single thread model works fine for normal execution, but for the instance like network call which are usually long operations, UI hangs waiting for the response from the server.
One of the methods that promptly come to our mind is to create a new thread and implements its run method for performing time consuming long operations.

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

The above approach of creating new thread for performing time consuming long operations would have worked fine but since Android implements single thread model and Android UI toolkit is not thread safe i.e. UI must always be updated in UI thread, updating UI view at the end of long operation may lead to some issues like UI hangs.

Following are the various mechanisms provided by android via which we can access UI thread from other threads.

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Handler

Let us look at each of them.

runOnUIThread

This activity method will run on UI thread. If the current thread is the UI thread, then the action is executed immediately. Or else the action is posted to the event queue of the UI thread.

	public void onClick(View v) {
		Thread t = new Thread(){
			public void run(){
				// Long time consuming operation
				_activity.runOnUiThread(new Runnable() {

					@Override
					public void run() {
						_activity.setStatus("Long Operation Completed");

					}
				});
			}
		};
		t.start();
	}

post & postDelayed

These methods are of view and are use for updating the view. They place action (Runnable) in the message queue and this runnable action runs on UI thread.

post

	public void onClick(View v) {
		// TODO Auto-generated method stub
		Thread t = new Thread(){
			@Override
			public void run() {
				// Long time consuming operation
				status.post(new Runnable() {

					@Override
					public void run() {
						status.setText("Long Operstion Completed");

					}
				});
			}
		};
		t.start();
	}

postDelayed

	public void onClick(View v) {
		// TODO Auto-generated method stub
		Thread t = new Thread(){
			@Override
			public void run() {
				// Long time consuming operation
				status.postDelayed(new Runnable() {

					@Override
					public void run() {
						status.setText("Long Operstion Completed");

					}
				}, 1000);
			}
		};
		t.start();
	}

As we can see the difference between the post and postDelayed is that postDelayed accepts one more parameter defining the delayed for the execution of action.

Handler

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

Above code snippets shows mechanism to create Handler. Here we have to override method handleMessage for Handler which accepts object of Message as paarameter.

Now look at the code snippet for long operation and see how this Handler is called.

	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();
	}

After the execution of long operation result is set in Message and passed to sendMessage of handler. Handler 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.

All the above said approaches enforces creation of thread and implementing its run() method. All this make code more complex and difficult to read. To simplify this process of performing long operation and updating UI, Android introduced AsyncTask.

AsyncTask

With AsyncTask android takes care of thread management leaving business login writing to us.
public class LongTimeConsumingOperation extends AsyncTask<String, Void, String> {

	@Override
	protected String doInBackground(String... params) {
		// perform Long time consuming operation
		return null;
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
	 */
	@Override
	protected void onPostExecute(String result) {
		// TODO Auto-generated method stub
		super.onPostExecute(result);
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onPreExecute()
	 */
	@Override
	protected void onPreExecute() {
		// TODO Auto-generated method stub
		super.onPreExecute();
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onProgressUpdate(Progress[])
	 */
	@Override
	protected void onProgressUpdate(Void... values) {
		// TODO Auto-generated method stub
		super.onProgressUpdate(values);
	}

}

For executing AsyncTask, call execute method as shown in onClick method.

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

Let us understand AsyncTask with the help of above example:

  • Extend class AsyncTask and implements its methods.
  • onPreExecute: This method is called before doInBackground method is called.
  • doInBackground: Code to perform long operations goes here.
  • onPostExecute: As the name suggest this method is called after doInBackground completes execution.
  • onProgressUpdate: Calling publishProgress anytime from doInBackground call this method.

onPostExecute, onPreExecute and onProgressUpdate is optional and need not be overridden.

Also look at how we have extended LongTimeConsumingOperation with AsyncTask and understand AsyncTask generics.

AsynTask<String, void, String>

Things to note here are:

  • 1st String represents Params i.e the type of parameter doInBackground method will accept and also represents the type of parameter execute method will accept.
  • 2nd void represent Progress i.e the parameter type for onProgressUpdate method
  • 3rd String represents Result i.e the type of parameter accepted by onPostExecute method

Rules to Remember

While implementing AsyncTask we need to remember following rules:

  • Task can be executed only once.
  • Instance of AsyncTask needs to be created in UI thread. As shown above in onClick method a new instance of LongTimeConsumingOperation is created.
  • execute method with parameters should be called from UI thread.
  • Methods onPostExecute, onPreExecute and onProgressUpdate should not be called explicitly.

Conculsion

Through AsyncTask android provides an robust way of performing task and handling UI updating.