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訊息處理機制原始碼Android
- Android中的非同步訊息處理機制Android非同步
- 深入理解Android非同步訊息處理機制Android非同步
- 理解 Android 訊息機制Android
- Android訊息機制HandlerAndroid
- android訊息機制—HandlerAndroid
- Android 之訊息機制Android
- Cloud Foundry架構和訊息處理機制Cloud架構
- Handler訊息處理機制原始碼解析 上原始碼
- 回轉壽司你一定吃過!——Android訊息機制(處理)Android
- Android非同步訊息機制Android非同步
- Android訊息機制Handler用法Android
- Android 訊息機制詳解(Android P)Android
- Android的Handler訊息機制 解析Android
- Android Handler 訊息機制詳述Android
- 深入理解Android訊息機制Android
- Android 訊息機制:Handler、MessageQueue 和 LooperAndroidOOP
- 全面剖析Android訊息機制原始碼Android原始碼
- Android Handler MessageQueue Looper 訊息機制原理AndroidOOP
- 由外到內——剖析Android訊息機制Android
- 06.Android之訊息機制問題Android
- Android進階;Handler訊息機制詳解Android
- Android Handler訊息機制原始碼解讀Android原始碼
- Android-Handler訊息機制實現原理Android
- 詳解 Handler 訊息處理機制(附自整理超全 Q&A)
- React應用裡Invalid hook call錯誤訊息的處理ReactHook
- Android訊息機制全面解析(Handler,MessageQueue,Looper,Threadlocal)AndroidOOPthread
- Android之Handler訊息傳遞機制詳解Android
- Android 12(S) 圖形顯示系統 - SurfaceFlinger的啟動和訊息佇列處理機制(四)Android佇列
- Android訊息機制,從Java層到Native層剖析AndroidJava
- Android原始碼解析之一 非同步訊息機制Android原始碼非同步
- Fuchsia最新訊息,確認支援Android應用Android
- 訊息機制篇——初識訊息與訊息佇列佇列
- Android Handler機制之迴圈訊息佇列的退出Android佇列
- Android Handler訊息傳遞機制:圖文解析工作原理Android
- android 訊息傳遞機制進階EventBus的深入探究Android
- Android全面解析之由淺及深Handler訊息機制Android
- MPLS RSVP訊息處理——VecloudCloud