Updating GUI: Runnables vs Messages

前端 未结 4 1644
再見小時候
再見小時候 2020-12-23 13:52

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

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

    Activity.r         
    
    
            
相关标签:
4条回答
  • 2020-12-23 13:54

    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

    0 讨论(0)
  • 2020-12-23 13:54

    I prefer Runnable to Message. I think code using Runnable is much clearer than Message, because the event handling code is very close to the event. Also, You can avoid the overhead of defining constants and switch cases.

    And I don't think using Runnable violates encapsulation. You can extract the code in Runnable.run() into another method in the outer class, for example on...Event(), or even wrap it into an EventHandler object. Both ways are much clearer than using Message, especially when you need store references in Message, because using Runnable avoids downcasting msg.obj. And the nameless field msg.obj is also error prone and sometimes inefficient to understand.

    And Runnable can also be reused by storing it as a field.

    0 讨论(0)
  • 2020-12-23 14:10

    Handler interface provides much more functionality than runOnUiThread(), according to docs:

    There are two main uses for a Handler:
    (1) to schedule messages and runnables to be executed as some point in the future
    (2) to enqueue an action to be performed on a different thread than your own.

    runOnUiThread does only a subset of (2). ie "enqueue an action to be performed on UI thread"

    So IMO unless you need those extra features runOnUiThread is sufficient and preferred way.

    0 讨论(0)
  • 2020-12-23 14:14

    Messages can be reused, so it results in fewer objects created and less GC. You also end up with fewer classes and anonymous types.

    One big advantage is that a class sending a Message to a Handler doesn't need to know anything about the implementation of that Message. That can aid in encapsulation depending on where it's used.

    Lastly consider the difference in cleanliness between

    mHandler.obtainMessage(DO_STUFF, foo).sendToTarget();
    

    vs

    final Foo tempFoo = foo;
    mHandler.post(new Runnable(){
        @Override
        public void run(){
            doStuff(tempFoo);
        }
    };
    

    If you have several places where you would have to doStuff(), the former is MUCH more readable and you'll have less code duplication.

    0 讨论(0)
提交回复
热议问题