Handler---4部曲 --- 1. 總體流程

Handler---4部曲---1. 總體流程
Handler---4部曲---2. ThreadLocal 存儲主流程
Handler---4部曲---3. MessageQueue隊列
Handler---4部曲---4.細節補充

爲什麼分4篇呢?
因爲我在看別人的博客中發現,人集中注意力的時間是有限的, 看太長時間容易累, 無法集中注意力,Handler的內容還是有點東西的.

一 . ActivityThread中的main方法
public static void main(String[] args) {
        Looper.prepareMainLooper();
        Looper.loop();
}

總結: App啓動, 執行2個方法.

1. Looper.prepareMainLooper()分析

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

    //Looper.java
    @Deprecated
    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) { //重複創建拋異常
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) { //重複創建拋異常
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        //創建Looper對象, 保存到sThreadLocal中
        sThreadLocal.set(new Looper(quitAllowed));
    }

    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
    }

總結:
1. 創建Looper對象(每個線程只有一個), 保存到sThreadLocal中
2. 創建隊列mQueue = new MessageQueue(...) , mQueue是Looper對象的成員變量

Looper.loop() 分析

   public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

public static void loop() {
         // 1.從sThreadLocal中, 獲取的Looper對象
        Looper me = myLooper(); 
        // 2.從Looper中, 獲取隊列
        MessageQueue queue = me.mQueue;
        for (;;) {
            //循環取出消息
            Message msg = queue.next();
            //處理消息
            msg.target.dispatchMessage(msg);
            //釋放資源
            msg.recycleUnchecked(); 
       }
}

總結:sThreadLocal--->取出當前線程Looper對象--->取出隊列, 循環從隊列取出消息處理

二. Handler發送消息

new Handler()
    public Handler(xxx) {
          mLooper = Looper.myLooper();
          mQueue = mLooper.mQueue;
    }

總結:從Looper中取出隊列, Handler中的mQueue 就是 Looper中的隊列

handler.post(xxx), handler.sendXxx(...)
    public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        enqueueMessage(queue, msg, uptimeMillis);
    }

    private boolean enqueueMessage(MessageQueue queue, Message msg,
            long uptimeMillis) {
        msg.target = this; //帶着當前的Handler.
        return queue.enqueueMessage(msg, uptimeMillis);
}

總結: msg攜帶當前的Handler對象, 加到隊列中.

總體流程完結

細節1:Main函數,不允許再次初始化.

細節2:每個線程只允許prepare()初始化一次

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章