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.
This is great. Can I create a thread that waits for a method that will call back?
ReplyDeleteThe example here is I am trying to bind to service simply to see if it exists. I need a way to know if we made the binding successfully before attempting to run methods in the interface. My stub object always returns null in my current code. I've noticed under regular memory conditions, this seems to take around 50-100ms for the system to complete the bind and call onServiceConnected.
So, I want the thread to wait for this success for around 200ms. The key is for it to return success if the onServiceConnected happens. In my UI I want to display a small spinning "refreshing" icon while this runs, but not an obstructing progress dialog as it should be a very short refresh.
I've been going by your example of handler for the remote service tutorial anytime I needed to create a thread that would delay any action or retry one based on time and it has worked great for my purposes thus far. I am using one that checks if the keyguard occurs after a sleep, allowing my process to react to the sleep that user doesn't abort by hitting any key to wake back up.
I know I could use that method and have the task check for a success flag every so often, but it seems it would be more efficient to create a thread capable of waiting for a set amount of time that could also receive a message of success at any time instead of relying on set check intervals.
Hi Ian
ReplyDeleteHere is what I think you should do:
1. Create a Handler in your client which starts the service and binds to the service.
2. This will associate a handler with your client process
3. Then, the sendMessage() method of the handler can be used in your onServiceConnected() method to send a success message back
4. The handleMessage() implementation within your handler created in the client class can process this message and take the required action.
I hope this helps. Let me know if this worked for you. All the best
**Here is the easier code for creating custom list-view with different images*
ReplyDeletewhich looks something like this image
![alt text][1]
firstly starts with creating UI....................
1.main.xml
2.row.xml
and add suitable images that you want to embed in your application
then start your main List Activity java class
3.Navigation.java
here is the main.xml
----------
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
now here is the code for Listview Images
row.xml
----------
now the main ListActivity java class where we have to create ListAdapter that manages a ListView backed by an array of arbitrary objects.
Navigation.java
package com.exercise.Navigation;
import com.exercise.Navigation.R;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class Navigation extends ListActivity
{public class MyCustomAdapter extends ArrayAdapter
{
public MyCustomAdapter(Context context, int textViewResourceId, String[] objects)
{ super(context, textViewResourceId, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.row, parent, false);
TextView label=(TextView)row.findViewById(R.id.navigation_item);
label.setText(item[position]);
ImageView icon=(ImageView)row.findViewById(R.id.icon);
if (item[position]=="Notes")
{
icon.setImageResource(R.drawable.notes);
}
if(item[position]=="H and P")
{
icon.setImageResource(R.drawable.hnp);
}
if(item[position]=="Imaging")
{
icon.setImageResource(R.drawable.imaging);
}
if(item[position]=="Vital")
{
icon.setImageResource(R.drawable.vital);
}
if(item[position]=="Problem")
{
icon.setImageResource(R.drawable.problem);
}
if(item[position]=="ADT")
{
icon.setImageResource(R.drawable.adt);
}
if(item[position]=="Notification")
{
icon.setImageResource(R.drawable.notification);
}
if(item[position]=="ECG")
{
icon.setImageResource(R.drawable.ecg);
}
return row;}}
String[] item = {"Notes","H and P","Imaging","Vital","Problem","ADT","Notification","ECG"};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setListAdapter(new MyCustomAdapter(Navigation.this, R.layout.row, item));
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id)
{
String selection = l.getItemAtPosition(position).toString();
Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
}
}
[1]: http://i.imgur.com/L78k5.png
Could'nt sendEmptyMessageDelayed(0,800) saved us from creating that thread ?
ReplyDeleteNice example though.
Sure, sendEmptyMessageDelayed(0,800) could have saved the thread if the thread is as is in the example shown, since nothing is really being done by the thread in this example. However, I am presuming this kind of code would be used to do time consuming tasks in that thread, as explained. In that case alone, we would want to spawn a thread.
ReplyDeleteHi, your tutorial is really helpful . but i am very new to this thread thing, so could you please help me to understand .
ReplyDeletenow i am not getting this handler.sendmessage(0). when any thread sends message using above method, where the message goes and what happens to that message.
If possible , please give your email-id so that i can contact you.
Hi,really nice tutorial.I have exercised your Thread tutorial .But I have one doubt that ,
ReplyDeletewhy handler is being used ,though we are using Thread.
I am not getting the significance of using handler to achieve Thread property.Kindly explain me.
Is it possible to avoid Handler ?
Thanks in advance.
Handlers are useful when u need to modify UI (say View.*), you can not modify it without handler or View.post() etc , otherwise system will through "CalledFromWrongThreadException".
ReplyDeleteHi wonderful article! it helped me to understand handler without any efforts. btw, i am reading on handler's post method. post(runnable) method to be specific. could you please explain it with a example.
ReplyDeletethank you again.
Hi
ReplyDeleteAll your blogs are very helpful for us.As i'm a beginner in android i feel so easy to learn from your blog. Now i'm stuck up in doing an application which is to receive a data from a remote Bluetooth device to my mobile device, i was able to discover and connect the devices through which i could send images and other files from my galaxy tab but i need to receive a data from another Bluetooth device. I would appreciate if you can help me in this.
Thanks in advance
TFS...nw more clear with android stuff....Thnks :)
ReplyDeleteHi Sai ......try to upload an article AsyncTask it will make the threading process simple...
ReplyDeletehi Sai....... Is file Loading process done by the worker Thread or the UI thread ,confuse about that. Or worker Thread show ProgressBar to end user and file Loading process done by UI thread
ReplyDeletereply soon
Android Beginner
Great one Sai... In its own simple ways it made me understand Handlers. I struggled to get a hold on this for long time.
ReplyDeleteThanks and keep up the good work.
Sunil
Great answer really it help me to under stand handler but you have put handleMessage(Message msg)inside the Handler class else every thing working fine
ReplyDeleteThank for great help .
Great explanation!!!!!!!!!!!!!!!!!
ReplyDeletethanks...
This comment has been removed by the author.
ReplyDeleteThis is what i was looking for. Great !!!
ReplyDeleteHi Sai,
ReplyDeleteGood explanation, really helped me with basics !!
Really good explanation for beginners ........Thanks
ReplyDeleteHi,
ReplyDeleteHow can I use handler for a turn based cards program?. Three Cpu players and one human player. In each turn, if it is the players turn , Cpus will wait for input from the UI, else they will execute in order. At the end of each turn , new order will be determined based on who wins the hand
Nice Thread Tutorial, i am new in android , its help me a lot ...
ReplyDeleteI have got some good links here
Thread_With_Handlers
its not understands to me
ReplyDeletecan u write clear documantation for this please
Thanks for this tutorial.Its very helpful for beginners.
ReplyDeletenice dear thanks for share also you can downloading more handler android in my site. hope you choice.
ReplyDelete