Android-Handler發(fā)送消息

Handler 發(fā)送消息

android中使用handler發(fā)送異步消息刷新UI是最基本的知識(shí)點(diǎn),但如何優(yōu)雅發(fā)送一個(gè)Message消息似乎很多人都是copy一個(gè)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();

區(qū)別

版本1->版本2的區(qū)別就是使用消息池復(fù)用消息不會(huì)重復(fù)創(chuàng)建Message對(duì)象,但版本2->版本3的區(qū)別是什么?網(wǎng)上很多文章說(shuō)了一大堆看的有點(diǎn)亂,我總結(jié)就一個(gè)句話更加優(yōu)雅了,非要說(shuō)出一個(gè)區(qū)別來(lái)就是sendToTarget()不能對(duì)new的Message(沒(méi)有target的Message)使用。

口說(shuō)無(wú)憑上源碼

先看Message類的obtain()這個(gè)方法

    /**
     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, 
     * <em>arg1</em>, and <em>arg2</em> members.
     * 
     * @param h  The <em>target</em> value to set.
     * @param what  The <em>what</em> value to set.
     * @param arg1  The <em>arg1</em> value to set.
     * @param arg2  The <em>arg2</em> 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其實(shí)就是handler對(duì)象,再看一下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();的實(shí)現(xiàn)

    /**
     * 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);就相當(dāng)于mHandler.sendMessage(message);,所以版本2的mHandler.sendMessage(...);和版本3的mHandler.obtainMessage(...).sendToTarget();是等價(jià)的。但版本3一行代碼就可以實(shí)現(xiàn)著實(shí)優(yōu)雅。

總結(jié)

使用mHandler.obtainMessage(...).sendToTarget();來(lái)優(yōu)雅的發(fā)送消息

測(cè)試用例

@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;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容