1. 程式人生 > >Handler訊息機制之流程解析

Handler訊息機制之流程解析

Hanlder中Messsage的傳送和處理過程

Handler.sendMessage()
-->MessageQueue.enqueueMessage()
-->Looper.next()
-->MessageQueue.next()
-->Handler.dispatchMessage()

通過一張圖片來加深理解:

在這裡插入圖片描述

Handler類原始碼分析

構造方法和屬性:

    final Looper mLooper;
    final MessageQueue mQueue;
    final Callback mCallback;
    final boolean mAsynchronous;
    
    IMessenger mMessenger;
    
    public Handler() {
        this(null, false);
    }
    public Handler(Callback callback) {
        this(callback, false);
    }
    public Handler(Looper looper) {
        this(looper, null, false);
    }
    public Handler(Looper looper, Callback callback) {
        this(looper, callback, false);
    }
    public Handler(boolean async) {
        this(null, async);
    }
    public Handler(Callback callback, boolean async) {
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
    public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

Message的傳送過程

先來,檢視sendMessage(): 從message物件新增進去,計算執行時間,最終新增到MessageQueue中。

    public final boolean sendMessage(Message msg){
        return sendMessageDelayed(msg, 0);
    }
    public final boolean sendMessageDelayed(Message msg, long delayMillis){
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

再來,看下post()方法:

   public final boolean post(Runnable r){
       return  sendMessageDelayed(getPostMessage(r), 0);
    }
    private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;//將Runnable與Message繫結
        return m;
    }

從以上可知,兩個方法最終都是轉成Message物件,放到MessageQueue佇列中,等待執行。

Message分發處理的過程

檢視Looper.looo()方法呼叫的dispatchMessage():

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
           //先呼叫Handler的CallBack介面
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            //後呼叫
            handleMessage(msg);
        }
    }
    //執行Message中Runnable介面的run()
    private static void handleCallback(Message message) {
        message.callback.run();
    }
    
    public void handleMessage(Message msg) {
    }

Handler類中的dispatchMessage()按以下順序來分發一個訊息:

  • 首先,若是Message中callback介面(實際上為Runnable介面)不為空,則執行callback介面物件的run()
  • 其次,若是Handler的mCallback不為空,則呼叫CallBack的handleMessage()
  • 最後才是,呼叫Handler的handleMessage()