天天看點

android handler的機制和原理_Handler機制原理

說到 Android 消息機制,就不得不談到 Handler 機制,接下來本文以 android-29 的源碼分析 Handler 機制的原理。

首先 Handler 是在 android.os 包下,與它在同一個包下的 Looper,Message,MessageQueue 等就是本文的重點。

// 舉個例子
           

這是 handler 在子線程使用的典型執行個體,下面按步驟分析:

1. Looper.prepare()

static 
           

調用後建立了 MessageQueue 和 Looper,并把 looper 的執行個體放入 ThreadLocal 中儲存

2. 建立 handler

Handler提供了兩種使用方式

第一種方式是直接執行個體化,調用handler的構造函數

//Handler.java#構造函數一
           

構造函數裡有三個參數,分别是

looper:建立了 MessageQueue,在某個線程中周遊對應的消息隊列,相當于發動機的角色。

callback:定義了 handleMessage() 方法,對接收到的消息進行處理,相當于快遞分揀員的角色。

async:設定消息是否異步,預設是同步的,如果是異步将不受同步障礙的限制。

第二種方式是繼承 handler,重寫 handleMessage() 方法。

建立 handler 後,handler 就持有了 looper 和 messageQueue 的對象引用, 通過調用 sendMessage() 方法往 messageQueue 中發送消息,其實最終調用的是 MessageQueue的enqueueMessage() 方法

boolean 
           

TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t))); 這行代碼會不斷地調用write()方法,直到管道中的資料全部讀完

3.Looper.loop()

//Looper.java#裁剪代碼
           

這裡重點分析 Message msg = queue.next();

Message 
           

mPtr的指派是nativeInit(),網上暫時沒找到Android Q的線上檢視,暫時以Android P來分析native層的邏輯。 native層建立NativeMessageQueue對象後将對象id傳回給java層,其中NativeMessageQueue建立時建立了Looper對象, 與java層Looper對象在建立時建立了MessageQueue對象恰恰相反

static 
           

nativePollOnce()調用到native層,将mPtr根據id轉為NativeMessageQueue對象

static 
           

至此流程分析結束,下面附上總結圖

android handler的機制和原理_Handler機制原理

Handler通過sendMessage()發送Message到MessageQueue隊列;

Looper通過loop(),不斷提取出達到觸發條件的Message,并将Message交給target來處理;

經過dispatchMessage()後,交回給Handler的handleMessage()來進行相應地處理。

将Message加入MessageQueue時,處往管道寫入字元,可以會喚醒loop線程;如果MessageQueue中沒有Message,并處于Idle狀态,則會執行IdelHandler接口中的方法,往往用于做一些清理性地工作。

android handler的機制和原理_Handler機制原理

Tips:

1.為什麼在主線程中使用handler不用調用Looper.prepareMainLooper()和Looper.loop()? 這是因為 ActivityThread 在初始化時已經調用過了,具體見如下源碼。

//ActivityThread.java#
           

2.主線程中的Looper.loop()一直無限循環為什麼不會造成ANR? 首先要明白ANR的定義,activity逾時5s,service逾時10s,broadcast逾時20s,才會導緻Application Not Response。

參考資料:

http://androidxref.com/http://gityuan.com/2015/12/26/handler-message-framework/http://gityuan.com/2015/12/27/handler-message-native/