Handler的異步消息處理運行機制,線程間通訊

1、引言

Android開發中老是免不了處理一些耗時的操做,如網絡請求、IO文件讀寫等等,都須要用子線程來處理,耗時操做每每也伴隨着更新UI的顯示。此時就涉及到UI線程與子線程之間的通訊問題。爲此Android系統引入了Handler異步消息處理的機制。java

2、在子線程中更新UI

Android中想要在子線程中更新UI,一般有三種辦法:網絡

  1. Handler的post方法
  2. View視圖控件的post方法
  3. Activity的runOnUiThread()方法

Handler的post方法,應該都很清楚,內部的Runnable的run方法已是在UI線程執行了。View的post方法、Activity的runOnUiThread()方法怎麼也能夠在UI線程呢,來看看其內部實現:架構

// View.java
public boolean post(Runnable action) {
    final AttachInfo attachInfo = mAttachInfo;
    if (attachInfo != null) {
        return attachInfo.mHandler.post(action);
    }

    // Postpone the runnable until we know on which thread it needs to run.
    // Assume that the runnable will be successfully placed after attach.
    getRunQueue().post(action);
    return true;
}

// Activity.java
public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }
複製代碼

很顯然從源碼能夠看出最終都是交給主線程Handler的post方法來處理。那麼爲何主線程聲明實例化的Handler的post方法在子線程調用就能夠用來更新UI呢?這個問題暫時先放這裏。接下來進一步分析Handler。異步

3、Handler的消息處理機制

在Handler的消息處理架構中,和Message、MessageQueue、Looper這三個類是緊密相連的。 Message:消息數據承載類,能夠是事件任務消息,也能夠是其它的實體數據消息。 MessageQueue:消息隊列。用於將消息入隊和出隊,以及消息從隊列刪除釋放的管理。 Looper:消息循環處理器。用於維持一個死循環不斷的從MessageQueue中取出消息,並將消息分發給設置的目標對象處理(target即Handler)。 Handler:它是整個機制的輔助類。也是提供給客戶端使用對外暴露Api。用於輔助把消息加入隊列、刪除釋放消息事件和消息的回調處理。oop

Handler中咱們最經常使用的有post()、postDelay()、sendMessage()等方法,直接或者間接的在內部構建一個Message消息對象而後經過MQ(MessageQueue)的enqueueMessage來處理消息入隊的工做。App啓動的時候在ActivityThread類的main方法裏就先經過prepareMainLooper方法預加載了一個Looper對象,而後經過loop方法開啓了消息循環器。post

// ActivityThread.java
public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    ...
    Looper.loop();
    ...
}
複製代碼

以上的Looper對象是主線程的,所以構造的MQ消息隊列也是主線程的,loop()方法中不斷循環取出隊列中的消息,經過handler的dispatchMessage方法分發消息。固然從一個事件消息的發送入隊到出隊處理回調不必定是實時的,MQ的enqueueMessage和next方法能夠看出它是一個單向鏈表隊列,入隊的時候根據消息發送的時間when按升序排序,當when爲0時插入到隊列頭部。spa

Handler異步消息處理運行機制原理圖
相關文章
相關標籤/搜索