Updating GUI: Runnables vs Messages

Mister Smith picture Mister Smith · Jun 26, 2012 · Viewed 9.2k times · Source

To update the GUI from other threads, there are basically two main approaches:

  1. Use java.lang.Runnable with any of these methods:

    Activity.runOnUiThread(Runnable)
    View.post(Runnable)
    View.postDelayed(Runnable, long)
    Handler.post(Runnable)
    
  2. Use android.os.Message:

    Handler.sendMessage(Message) / Handler.handleMessage(Message)
    

You can also use AsyncTask, but my question is more focused on the use case of updating a very simple component. Let's see how it would be done using both approaches:

  1. Using Runnables:

    TextViev tv = ...;
    final String data = "hello";
    Runnable r = new Runnable() {
    
        @Override
        public void run(){
            tv.setText(data);
        }
    
    };
    //Now call Activity.runOnUiThread(r) or handler.post(r), ...
    
  2. Using messages:

    Message m = handler.obtainMessage(UPDATE_TEXT_VIEW, "hello");
    handler.sendMessage(m);
    
    //Now on handler implementation:
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == UPDATE_TEXT_VIEW){
                String s = (String) msg.obj;
                tv.setText(data);
            } ... //other IFs?
        }
    

IMHO, Messages are not the way to go because:

  • Not easy to understand for new non-android programmers (handler hooks to its thread during construction).
  • Object payload should be Parcellable if the message crosses process boundaries.
  • Messages are reused (error prone if not properly cleaned up?)
  • The handler has a dual role (it sends messages, but also handles them)
  • Message attributes are public, but also offer getter/setter.

On the other hand, Runnables follow the well known command pattern, and are more programmer-friendly and readable.

So what are the advantages of using Messages over Runnables? Are Messages pushed into the background in modern day Android programming? Is there anything you can do with Messages that can't be done with Runnables?

Thanks in advance.

Answer

Jay Soyer picture Jay Soyer · Mar 20, 2014

I would say there is little difference between using a Message vs a Runnable. It'll mostly boil down to personal preference. Why? Looking at the source code you'll find that posting a Runnable uses the same exact messaging mechanism. It simply attaches the Runnable to a Message and sends that.

4.4.2 Source Code

public final boolean post(Runnable r) {
    return  sendMessageDelayed(getPostMessage(r), 0);
}

private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}

Ref: Grep Code - Handler