Handler、Looper與MessageQueue之間的關(guān)系

  • Handler 封裝了消息的發(fā)送,也負(fù)責(zé)接收消息,內(nèi)部會與Looper 關(guān)聯(lián)
  • Looper封裝了線程中的消息循環(huán),內(nèi)部包含了MessageQueue,負(fù)責(zé)從MessageQueue取出消息,然后交給Handler 處理
  • MessageQueue就是一個消息隊列,負(fù)責(zé)存儲消息,收到消息就存儲起來,Looper會循環(huán)從MessageQueue讀取消息

  1. Handler
public Handler(Callback callback, boolean async) {
    // ...
    mLooper = Looper.myLooper();
    // ...
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}
  1. Looper.myLooper()
public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

sThreadLocal 是一個 ThreadLocal 對象,可以在一個線程中存儲變量。底層是 ThreadLocalMap(一個Map類型)

  1. ActivityThread.main()

ActivityThread 是 Android App進程的初始類,main函數(shù)是App進程的入口。

public static final void main(String[] args) {
    Looper.prepareMainLooper();
    if(sMainThreadHandler == null) {
        sMainThreadHandler = new Handler();
    }

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if(false) {
        Looper.myLooper().sendMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    Looper.loop();
}
  1. Looper.prepareMainLooper()
public static void prepareMainLooper() {
    prepare(false);
    synchronized (Looper.class) {
        if(sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper = myLooper();
    }
}

該方法會新建一個 Looper 對象并存儲在 sThreadLocal 中。

  1. Looper.prepare()
private static void prepare(boolean quitAllowed) {
    if(sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}
  1. Looper 構(gòu)造器
private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}
  1. Looper.loop()

該方法是一個死循環(huán),會一直從 MessageQueue 中獲取消息。如果獲取到消息,就會執(zhí)行 msg.target.dispatchMessage(msg),其中 msg.target 就是 Handler 對象,也就是調(diào)用 Handler 的 dispatchMessage() 方法,然后將從 MessageQueue 中獲取的消息傳入。

  1. Handler.dispatchMessage() 方法

dispatchMessage() 方法對消息進行最后的處理,如果是 post 類型,就調(diào)用 handlerCallback 方法處理,否則是 sendMessage 發(fā)送的消息。先查看是否有攔截,如果沒有,最終就調(diào)用 handlerMessage 方法進行處理。


public void dispatchMessage(Message msg) {
    // 如果 callback 不為空,說明發(fā)送消息時是發(fā)送一個 Runnable 對象
    if(msg.callback != null) {
        handleCallback(msg);
    } else {
        if(mCallback != null) { // 這是用來攔截消息的
            if(mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg); // 最終調(diào)用重寫的 handleMessage() 方法
    }
}

  1. Handler.handleCallback()
private static void handleCallback(Message msg) {
    msg.callback.run();
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容