當前位置:編程學習大全網 - 遊戲軟體 - android postDelayed實現

android postDelayed實現

2015-01-18 12:00

在android中做延時處理壹般用handler.postDelayed()和view.postDelayed(action,delay)來實現,view.postDelayed也是通過handlder.postDelayed來實現的,不過有壹些特殊處理的地方。

handler處理延時邏輯是通過發送延時消息來處理的

sendMessageDelayed:

sendMessageAtTime:

將延時消息放入到消息隊列中。SystemClock.uptimeMillis()是開機到現在的時間(毫秒),不包括睡眠的時間。不用System.currentTimeMillis()的原因是System.currentTimeMillis()的時間是可以被System.setCurrentTimeMillis修改的,如果被修改了則發生難以想象的後果。

enqueueMessage調用MessageQueue.enqueueMessage(msg,uptimeMillis)

此處會將傳入的消息對象根據觸發時間(when)插入到message queue中。然後判斷是否要喚醒等待中的隊列。

. 如果插在隊列中間。說明該消息不需要馬上處理,不需要由這個消息來喚醒隊列。

. 如果插在隊列頭部(或者when=0),則表明要馬上處理這個消息。如果當前隊列正在堵塞,則需要喚醒它進行處理。

通過nativeWake方法喚醒隊列。

looper執行MessageQueue中的消息:

只是調用了MessageQueue.next()方法。可能會阻塞。

該方法會先調用nativePollOnce阻塞,然後進入死循環。nativePollOnce()的作用類似與object.wait(),使用了native方法來對線程進行精確時間的喚醒,

如果head Message是有延遲而且延遲時間沒到的(now < msg.when),計算下時間間隔(nextPollTimeoutMillis),設置timeout為兩者之差,進入下壹次循環。

如果Message無延時或已到達執行時間,則直接返回該Message.

如果當前的Message阻塞住了MessageQueue(pendingIdleHandlerCount <= 0),把全局變量mBlocked改為true,在下壹個Message放入隊時會判斷這個message的位置。如果在queue的頭部,則用nativeWake喚醒線程。

總結:[msg loop] -->調用MessageQueue.next(),若頭部的消息需要被執行在返回該消息,send該消息之後繼續調用next方法獲取下壹個消息,若頭部的不需要被執行則阻塞住隊列,若有等待執行的Message,計算壹下剩余時間,繼續調用nativePollOnce()阻塞,無限循環到阻塞時間到或者下壹次有Message進隊。下個消息進隊時若不需要延時在放在Queue的頭部,否則在放在Queue的中部。

view的延時也是調用了handler的postDelayed.

若view的AttachInfo不為空,則調用AttachInfo中的handler的postDelayed。若AttachInfo為空,則先將action放入RunQueue中。RunQueue為HandlerActionQueue,用來存放view沒有handler時的action。

執行action:

還是需要傳入壹個Handler,利用handler來執行action。當view被關聯到window時,會執行該隊列中的Action.

AttachInfo是View的壹個附加信息存儲類,當view被關聯到window時會被賦值。

  • 上一篇:天下文章壹大抄,《卡片筆記寫作法》告訴妳,如何做到“會抄”
  • 下一篇:四分之壹是什麽意思
  • copyright 2024編程學習大全網