Handler的post()方法解析

一、先從源碼看起:

mHandler.post(new Runnable(){

? ? ? ? ? ?@Override

? ? ? ? ? ? public void run(){

? ? ? ? ? ? ? ? ? ? ? ?//TODO

? ? ? ? ? ? ? }

});

其中run方法中寫更新UI的代碼,其實只是把這個Runnable當(dāng)成一條消息來處理,下面看源碼:


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;

}

可以看到,在getPostMessage中,得到了一個Message對象,然后將我們創(chuàng)建的Runable對象作為callback屬性,賦值給了此message.

注:產(chǎn)生一個Message對象,可以new ?,也可以使用Message.obtain()方法;兩者都可以,但是更建議使用obtain方法,因為Message內(nèi)部維護(hù)了一個Message池用于Message的復(fù)用,避免使用new 重新分配內(nèi)存。


public final boolean sendMessageDelayed(Message?msg,long delayMillis)

{

? ? ? ? ? ? ? ?if(delayMillis?<0)?{

? ? ? ? ? ? ? ? ? ? ? ? ? delayMillis?=0;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ?return sendMessageAtTime(msg,?SystemClock.uptimeMillis()?+?delayMillis);

}


public boolean sendMessageAtTime(Message?msg,long uptimeMillis)?{

? ? ? ? ? ? ? ? MessageQueue?queue?=?mQueue;

? ? ? ? ? ? ? ? if(queue?==null)?{

? ? ? ? ? ? ? ? ? ? ? ? ? RuntimeException?e?=new RuntimeException(

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? this+"?sendMessageAtTime()?called?with?no?mQueue");

? ? ? ? ? ? ? ? ? ? ? ? ? ?Log.w("Looper",?e.getMessage(),?e);

? ? ? ? ? ? ? ? ? ? ? ? ? ?return false;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? return enqueueMessage(queue,?msg,?uptimeMillis);

}

最終和handler.sendMessage一樣,調(diào)用了sendMessageAtTime,然后調(diào)用了enqueueMessage方法,給msg.target賦值為handler,最終加入MessagQueue.

可以看到,這里msg的callback和target都有值,那么會執(zhí)行哪個呢?

其實上面已經(jīng)貼過代碼,就是dispatchMessage方法:

public void dispatchMessage(Message?msg)?{

? ? ? ? ? ? if(msg.callback?!=null)?{

? ? ? ? ? ? ? ? ? ? ?handleCallback(msg);

? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? ? ? if(mCallback?!=null)?{

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if(mCallback.handleMessage(msg))?{

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? handleMessage(msg);

? ? ? ? ?}

}

第2行,如果不為null,則執(zhí)行callback回調(diào),也就是我們的Runnable對象。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容