NOTE:

NOTE: Of late, I have been getting requests for very trivial problems that many of you are facing in your day-to-day work. This blog is not to solve your "project" problems - surely not a "Support" site.
I just love to share my knowledge in my spare time and would appreciate any questions or feedback on the articles and code I have shared. I also do appreciate thought-provoking questions that would lead me to write more articles and share.
But please do not put your day-to-day trivial problems here. Even if you do, you most probably would not get a response here.
Thanks

Search This Blog

x

Tuesday 27 April 2010

Threads and Handlers | Android Developer Tutorial (Part 18)

Any mobile software development needs to be done with an awareness of the end user experience. This is true in any other domain as well. But special mention here on mobile development as end users are used to responsive apps on the mobile and any small delay is perceived as un-responsiveness or worse – that the application has hung.

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

start.setOnClickListener(new OnClickListener() {});
@Override
public void onClick(View arg0) {
fetchData();
}
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:

protected void fetchData() {


progressDialog = ProgressDialog.show(this, "", "Doing...");


new Thread() {


public void run() {
try {
    Thread.sleep(800);} catch (InterruptedException e) {
}
messageHandler.sendEmptyMessage(0);
}
       }.start();
    }


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.

25 comments:

  1. This is great. Can I create a thread that waits for a method that will call back?

    The 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.

    ReplyDelete
  2. Hi Ian

    Here 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

    ReplyDelete
  3. **Here is the easier code for creating custom list-view with different images*

    which 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

    ReplyDelete
  4. Could'nt sendEmptyMessageDelayed(0,800) saved us from creating that thread ?

    Nice example though.

    ReplyDelete
  5. 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.

    ReplyDelete
  6. Hi, your tutorial is really helpful . but i am very new to this thread thing, so could you please help me to understand .

    now 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.

    ReplyDelete
  7. Hi,really nice tutorial.I have exercised your Thread tutorial .But I have one doubt that ,

    why 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.

    ReplyDelete
  8. 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".

    ReplyDelete
  9. Hi 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.

    thank you again.

    ReplyDelete
  10. Hi
    All 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

    ReplyDelete
  11. TFS...nw more clear with android stuff....Thnks :)

    ReplyDelete
  12. Hi Sai ......try to upload an article AsyncTask it will make the threading process simple...

    ReplyDelete
  13. hi 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

    reply soon
    Android Beginner

    ReplyDelete
  14. Great one Sai... In its own simple ways it made me understand Handlers. I struggled to get a hold on this for long time.
    Thanks and keep up the good work.
    Sunil

    ReplyDelete
  15. 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
    Thank for great help .

    ReplyDelete
  16. Great explanation!!!!!!!!!!!!!!!!!
    thanks...

    ReplyDelete
  17. This comment has been removed by the author.

    ReplyDelete
  18. This is what i was looking for. Great !!!

    ReplyDelete
  19. Hi Sai,
    Good explanation, really helped me with basics !!

    ReplyDelete
  20. Really good explanation for beginners ........Thanks

    ReplyDelete
  21. Hi,

    How 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

    ReplyDelete
  22. Nice Thread Tutorial, i am new in android , its help me a lot ...

    I have got some good links here

    Thread_With_Handlers

    ReplyDelete
  23. its not understands to me
    can u write clear documantation for this please

    ReplyDelete
  24. Thanks for this tutorial.Its very helpful for beginners.

    ReplyDelete
  25. nice dear thanks for share also you can downloading more handler android in my site. hope you choice.

    ReplyDelete