Android應用程式訊息處理機制
原文連結:http://www.apkbus.com/blog-705730-61240.html
Android的訊息處理機制主要分為四個部分:
· 建立訊息佇列
· 訊息迴圈
· 訊息傳送
· 訊息處理
主要涉及三個類:
· MessageQueue
· Looper
· Handler
Android應用程式每啟動一個執行緒,都為其建立一個訊息佇列,然後進入到一個無限迴圈之中。然後不斷檢查佇列中是否有新訊息需要處理。如果沒有,執行緒就會進入睡眠狀態,反之會對訊息進行分發處理。
下面根據上面所說的進行詳述。
建立訊息佇列
整個建立過程涉及到兩個類:MessageQueue 和 Looper。它們在C++層有兩個對應的類:NativeMessageQueue和Looper。其關係如下圖所示:
1 2 3 4 5 6 7 8 9 10 11 12 |
+------------+ +------+ |MessageQueue+----^+Looper| +-----+------+ +------+ | | | +-----------+------+ +------+ |NativeMessageQueue+^----+Looper| +------------------+ +------+
A----^B表示B中儲存A的引用
|
建立過程如下所示:
1. Looper的prepare或者prepareMainLooper靜態方法被呼叫,將一個Looper物件儲存在ThreadLocal裡面。
2. Looper物件的初始化方法裡,首先會新建一個MessageQueue物件。
3. MessageQueue物件的初始化方法透過JNI初始化C++層的NativeMessageQueue物件。
4. NativeMessageQueue物件在建立過程中,會初始化一個C++層的Looper物件。
5. C++層的Looper物件在建立的過程中,會在內部建立一個管道(pipe),並將這個管道的讀寫fd都儲存在mWakeReadPipeFd和mWakeWritePipeFd中。
然後新建一個epoll例項,並將兩個fd註冊進去。
6. 利用epoll的機制,可以做到當管道沒有訊息時,執行緒睡眠在讀端的fd上,當其他執行緒往管道寫資料時,本執行緒便會被喚醒以進行訊息處理。
訊息迴圈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
+------+ +------------+ +------------------+ +--------------+ |Looper| |MessageQueue| |NativeMessageQueue| |Looper(Native)| +--+---+ +------+-----+ +---------+--------+ +-------+------+ | | | | | | | | +-------------------------------------------------------------------------------+ |[msg loop] | next() | | | | | +------------> | | | | | | | | | | | | | | | | | | | nativePollOnce() | | | | | | pollOnce() | | | | | +----------------> | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | pollOnce() | | | | | +-----------------> | | | | | | | | | | | | | epoll_wait() | | | | +--------+ | | | | | | | | | | | | | | | | | | | | | | | | | awoken() | | + + + + | | | | | +-------------------------------------------------------------------------------+
|
1. 首先透過呼叫Looper的loop方法開始訊息監聽。loop方法裡會呼叫MessageQueue的next方法。next方法會堵塞執行緒直到有訊息到來為止。
2. next方法透過呼叫nativePollOnce方法來監聽事件。next方法內部邏輯如下所示(簡化):
a. 進入死迴圈,以引數timout=0呼叫nativePollOnce方法。
b. 如果訊息佇列中有訊息,nativePollOnce方法會將訊息儲存在mMessage成員中。nativePollOnce方法返回後立刻檢查mMessage成員是否為空。
c. 如果mMessage不為空,那麼檢查它指定的執行時間。如果比當前時間要前,那麼馬上返回這個mMessage,否則設定timeout為兩者之差,進入下一次迴圈。
d. 如果mMessage為空,那麼設定timeout為-1,即下次迴圈nativePollOnce永久堵塞。
3. nativePollOnce方法內部利用epoll機制在之前建立的管道上等待資料寫入。接收到資料後馬上讀取並返回結果。
訊息傳送
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
+-------+ +------------+ +------------------+ +--------------+ |Handler| |MessageQueue| |NativeMessageQueue| |Looper(Native)| +--+----+ +-----+------+ +---------+--------+ +-------+------+ | | | | | | | | sendMessage()| | | | +----------> | | | | | | | | |enqueueMessage()| | | +--------------> | | | | | | | | | | | | | | | | | nativeWake() | | | | wake() | | | +------------------> | | | | | | | | | wake() | | | +------------------> | | | | | | | | | | | | |write(mWakeWritePipeFd, "W", 1) | | | | | | | | | | | | | | | | | | | | + + + +
|
訊息傳送過程主要由Handler物件來驅動。
1. Handler物件在建立時會儲存當前執行緒的looper和MessageQueue,如果傳入Callback的話也會儲存起來。
2. 使用者呼叫handler物件的sendMessage方法,傳入msg物件。handler透過呼叫MessageQueue的enqueueMessage方法將訊息壓入MessageQueue。
3. enqueueMessage方法會將傳入的訊息物件根據觸發時間(when)插入到message queue中。然後判斷是否要喚醒等待中的佇列。
a. 如果插在佇列中間。說明該訊息不需要馬上處理,不需要由這個訊息來喚醒佇列。
b. 如果插在佇列頭部(或者when=0),則表明要馬上處理這個訊息。如果當前佇列正在堵塞,則需要喚醒它進行處理。
4. 如果需要喚醒佇列,則透過nativeWake方法,往前面提到的管道中寫入一個”W”字元,令nativePollOnce方法返回。
訊息處理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
+------+ +-------+ |Looper| |Handler| +--+---+ +---+---+ | | | | loop() | | [after next()] | +---------> | | | | |dispatchMessage() +-------------> | | | | | | | handleMessage() | +-------+ | | | | | | | | | | (callback or subclass) | | + +
|
Looper物件的loop方法裡面的queue.next方法如果返回了message,那麼handler的dispatchMessage會被呼叫。
a. 如果新建Handler的時候傳入了callback例項,那麼callback的handleMessage方法會被呼叫。
b. 如果是透過post方法向handler傳入runnable物件的,那麼runnable物件的run方法會被呼叫。
c. 其他情況下,handler方法的handleMessage會被呼叫。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/755/viewspace-2814843/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Android應用程式訊息處理機制(Looper、Handler)分析AndroidOOP
- Windows應用程式的訊息處理機制Windows
- 原始碼分析:Android訊息處理機制原始碼Android
- Android 訊息處理機制:Handler|MessageAndroid
- Android中的非同步訊息處理機制Android非同步
- 深入理解Android非同步訊息處理機制Android非同步
- Android訊息處理機制(Handler、Looper、MessageQueue與Message)AndroidOOP
- 如何生動形象的理解Android Handler訊息處理機制Android
- MFC應用程式中處理訊息的順序
- Cloud Foundry架構和訊息處理機制Cloud架構
- Handler訊息處理機制原始碼解析 上原始碼
- Service初探與非同步訊息處理機制非同步
- Looper中的訊息佇列處理機制OOP佇列
- Android非同步訊息處理機制詳解及原始碼分析Android非同步原始碼
- Android訊息機制Message訊息池Android
- android訊息機制—HandlerAndroid
- 理解 Android 訊息機制Android
- Android訊息機制HandlerAndroid
- Android 之訊息機制Android
- Android的訊息機制Android
- Android程式間通訊–訊息機制及IPC機制實現薦Android
- android之 Android訊息機制Android
- Android訊息傳遞之Handler訊息機制Android
- 回轉壽司你一定吃過!——Android訊息機制(處理)Android
- Android非同步訊息機制Android非同步
- Android訊息機制Handler用法Android
- Android 訊息機制詳解Android
- Android訊息機制(七) RxjavaAndroidRxJava
- OC訊息機制,訊息轉發機制
- [Android進階]Android訊息機制Android
- Android應用AsyncTask處理機制詳解及原始碼分析Android原始碼
- Android Handler 訊息機制詳述Android
- Android的Handler訊息機制 解析Android
- 深入理解Android訊息機制Android
- Android訊息機制原始碼分析Android原始碼
- 訊息機制
- Android 訊息機制詳解(Android P)Android
- MFC訊息響應機制分析 (轉)