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
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.
jerome
Aug 02, 2010 @ 19:49:45
I’m noob to real android coding but, to me, a runnable definrd in a thread looks unfriendly
krishna
Jun 25, 2011 @ 20:13:14
thanks prashanth…..its helpful
prami
May 04, 2013 @ 06:52:38
thanks good explanation.
Kamal
Jul 30, 2013 @ 10:29:17
Nice Explanation!!!