Android訊息迴圈

陳順發表於2014-02-22

Android的訊息迴圈由Looper、MessageQueue、Message、Handler組成,Looper和MessageQueue是內部的,驅動訊息迴圈運轉的部件,Message和Handler是外部使用的,外部通過Handler向訊息迴圈系統傳送訊息和或者刪除訊息。

Message有一個時間屬性,這是一個很重要的屬性,因為它表明了Message將在什麼時候被髮送給接收者,這個時間不是日曆時間,而是從裝置開機後消逝的時間(SystemClock.uptimeMillis)。

Handler負責將Message插入到MessageQueue中,並且也扮演了Message的接收者的角色。

MessageQueue按佇列的形式組織Message,並且按Message的時間給佇列中的Message排序,時間近的排在前頭,時間晚的排在後頭。

所以當向MessageQueue插入一個Message時,會遵守這個按時間的排序規則,找到合適的位置把Message插進去,而不是簡單地插在佇列的尾部。

當從MessageQueue中取一個Message時,由於Message都按時間排了序,所以取出佇列前頭的第一個訊息,然後檢視它的時間到點了沒有,如果到點了或者錯過了就把它取出來,如果還沒有到點,那就看看還需要等待多長時間到點,然後就等待那麼長時間再把它取出來。

在等待的過程中,訊息迴圈所在的執行緒是睡眠的,如果這個時候又有訊息插入進來,那麼就喚醒這個執行緒,讓它按照上面的方式再取一次訊息,如此反覆直到有某段程式碼主動停止了這個訊息迴圈。如果MessageQueue中沒有訊息,那麼就會無限地等待下去,直到某個被插入進來的訊息喚醒了它。

Handler可以向MessageQueue插入延時訊息,其實就是把Message的時間設定在未來的某一個時刻,然後插入到MessageQueue中,MessageQueue按照上面的方式取訊息時,就會在那個時刻把訊息取出來。

Looper是負責分發訊息的,從MesasgeQueue中取出的Mesage是要交給Looper的,Looper將得到的Message傳送給正確的接收者。為什麼Looper不會把訊息發錯呢?因為Message上已經寫明瞭誰是接收者。

為了讓多個執行緒也能往這個執行緒傳送訊息,MessageQueue被賦予了執行緒安全的能力,它能保證在多個執行緒同時向它傳送訊息或刪除訊息時不會出問題。

Looper分發訊息的過程和向MessageQueue插入訊息的過程時相互獨立的,誰也影響不了誰。Looper在分發訊息時可能因為接收者處理得比較慢,這個時候要等上一會,但不會影響其他執行緒往MessageQueue插入訊息,其他執行緒不會因為前面訊息接收者的慢動作而受到阻塞。

其實相互之間有影響的是,從MessageQueue取訊息的操作和多個執行緒向MessageQueue插入訊息的操作,這些操作中,任何一個在進行時,其他操作必須等待。等待的時間取決於MessageQueue中有多少個訊息,以及在多長時間內把這些訊息遍歷完。

相關文章