One of the basic principles to provide a very responsive application is to handle any time consuming code in a separate thread – not the main thread or the UI thread as it is also known. So, it is very essential to understand about how to spawn new threads (worker or background threads) and how to come back to the parent thread.
How do the 2 threads (parent/UI and the worker threads) communicate? Here comes the Handler. By definition – “A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue.”
So, let us take the handler from the main thread and see how we can use it to communicate with a child thread.
When a handler is created, it is associated by default with the current thread. So, we have this piece of code in the main activity class:
Now, I spawn a new thread through a method that is called when I click a button. So, let us see the button piece of code first:
private Handler messageHandler = new Handler() {
};
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDialog.dismiss();
}
start = (Button) findViewById(R.id.Button01);Now, on click of the button, the fetchData() method is invoked. Assuming that this is a very time consuming task, I will spawn a thread and do the task and return from that thread as shown in the code below:
start.setOnClickListener(new OnClickListener() {});
@Override
public void onClick(View arg0) {
fetchData();
}
protected void fetchData() {}.start();
progressDialog = ProgressDialog.show(this, "", "Doing...");
new Thread() {
public void run() {
try {
Thread.sleep(800);} catch (InterruptedException e) {
}
messageHandler.sendEmptyMessage(0);
}
}
Since it is time consuming, I am starting a ProgressDialog just to inform the end user that some activity is happening. Then, I start the thread, make it sleep for 800 milliseconds and send back an empty message through the message handler. The messageHandler.sendEmptyMessage(0) is the callback on the parent thread’s messageHandler to inform that the child thread has finished its work. In this example I am sending an empty message. But this can be the means of communication and exchange of data from the child thread to the parent Thread.
Now the control returns to handleMessage() call back method. That method shown in the beginning just dismisses the progressDialog.
In real life cases, within this thread we can do things like calling web-services, calling web-sites to fetch specific data or doing network IO operations and returning actual data that needs to be displayed on the front-end.
I will take up an example of an HTTP call invoked through such a thread in the next tutorial.
Also note that the Android UI toolkit is not thread-safe and must always be manipulated on the UI thread only. So the child thread should return all data and the painting of the UI should be left to the main thread or any UI specific thread.
There is a better way of handling this through the use of AsyncTask, a utility class available from SDK 1.5 onwards. It was available as UserTask earlier.
Here is the complete downloadable code for this tutorial.