Android-Handler发送消息

Handler 发送消息

android中使用handler发送异步消息刷新UI是最基本的知识点,但如何优雅发送一个Message消息似乎很多人都是copy一个handler.sendMessage(...)

handler消息演变

        //版本1
        Message message = new Message();
        message.what = 0;
        message.obj = "hello";
        mHandler.sendMessage(message); 
        
        ↓
        
        //版本2
        Message message = mHandler.obtainMessage();
        message.what = 0;
        message.obj = "hello";
        mHandler.sendMessage(message);
        
        ↓
        
        //版本3
        mHandler.obtainMessage(0,"hello").sendToTarget();

区别

版本1->版本2的区别就是使用消息池复用消息不会重复创建Message对象,但版本2->版本3的区别是什么?网上很多文章说了一大堆看的有点乱,我总结就一个句话更加优雅了,非要说出一个区别来就是sendToTarget()不能对new的Message(没有target的Message)使用。

口说无凭上源码

先看Message类的obtain()这个方法

    /**
     * Same as {@link #obtain()}, but sets the values of the target, what, 
     * arg1, and arg2 members.
     * 
     * @param h  The target value to set.
     * @param what  The what value to set.
     * @param arg1  The arg1 value to set.
     * @param arg2  The arg2 value to set.
     * @return  A Message object from the global pool.
     */
    public static Message obtain(Handler h, int what, int arg1, int arg2) {
        Message m = obtain();
        m.target = h;
        m.what = what;
        m.arg1 = arg1;
        m.arg2 = arg2;

        return m;
    }

target其实就是handler对象,再看一下Handler.obtainMessage()方法

    /**
     * 
     * Same as {@link #obtainMessage()}, except that it also sets the what and obj members 
     * of the returned Message.
     * 
     * @param what Value to assign to the returned Message.what field.
     * @param obj Value to assign to the returned Message.obj field.
     * @return A Message from the global message pool.
     */
    public final Message obtainMessage(int what, Object obj)
    {
        return Message.obtain(this, what, obj);
    }

最后看一下msg.sendToTarget();的实现

    /**
     * Sends this Message to the Handler specified by {@link #getTarget}.
     * Throws a null pointer exception if this field has not been set.
     */
    public void sendToTarget() {
        target.sendMessage(this);
    }

target.sendMessage(this);就相当于mHandler.sendMessage(message);,所以版本2的mHandler.sendMessage(...);和版本3的mHandler.obtainMessage(...).sendToTarget();是等价的。但版本3一行代码就可以实现着实优雅。

总结

使用mHandler.obtainMessage(...).sendToTarget();来优雅的发送消息

测试用例

@RunWith(AndroidJUnit4.class)
@LargeTest
public class HandlerAndroidTest {

    @Test
    public void testHandler() {
        Message msg = mHandler.obtainMessage(0, "hello");
        mHandler.sendMessage(msg);
        msg.sendToTarget();


        Message message = new Message();
        message.what = 0;
        message.obj = "new hello";
        mHandler.sendMessage(message);
    }

    @Before
    public void setUp() throws Exception {
        mHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                Log.e(TAG, "callback handle message:" + msg);
                return false;
            }
        }) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Log.e(TAG, "override handle message:" + msg);
            }
        };
    }

    final String TAG = "HandlerTest";
    private Handler mHandler;
}

你可能感兴趣的:(Android-Handler发送消息)