android-View.post與Handler.post的區別
阿新 • • 發佈:2019-01-28
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到來的時候。