1. 程式人生 > >android-View.post與Handler.post的區別

android-View.post與Handler.post的區別

View.postDelayed


package android.view;


public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {

    public boolean postDelayed(Runnable action, long delayMillis) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return
attachInfo.mHandler.postDelayed(action, delayMillis); } // Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().postDelayed(action, delayMillis); return true; } }

Handler.postDelayed


package android.os;

public class Handler {

    public final boolean postDelayed(Runnable r, long delayMillis)
    {
        return sendMessageDelayed(getPostMessage(r), delayMillis);
    }

}

View.postDelayed與Handler.postDelayed的區別

當View已經attach到了window,兩者是沒有區別的,都是呼叫UI執行緒的Handler傳送runnable到MessageQueue,最後都是由handler進行訊息的分發處理。

但是如果View尚未attach到window的話,runnable被放到了ViewRootImpl#RunQueue中,最終也會被處理,但不是通過MessageQueue。

當檢視樹尚未attach到window的時候,整個檢視樹是沒有Handler的(其實自己可以new,這裡指的handler是AttachInfo裡的),這時候用RunQueue來實現延遲執行runnable任務,並且runnable最終不會被加入到MessageQueue裡,也不會被Looper執行,而是等到ViewRootImpl的下一個performTraversals時候,把RunQueue裡的所有runnable都拿出來並執行,接著清空RunQueue。

由此可見RunQueue的作用類似於MessageQueue,只不過,這裡面的所有
runnable最後的執行時機,是在下一個performTraversals到來的時候,MessageQueue裡的訊息處理的則是下一次loop到來的時候。

參考: