Android Handler理解

Handler是什麼

Handler是Android 線程間通訊工具類。ide

通常用於子線程向主線程發送消息,將子線程中執行結果通知主線程,從而在主線程中執行UI更新操做。工具

源碼角度理解  

Handler負責發送(sendMessage)和處理消息(handleMessage)oop

1)Message:消息載體,包含消息id(what)、消息處理對象(obj)、Runnable接口等。Handler發送一條消息後,會將該消息加入到MessageQueue統一消息處理隊列中。學習

2)MessageQueue:消息隊列。用來存放Handler發送的消息的隊列,單鏈表實現ui

3)Looper:消息泵,經過Looper.loop( )建立一個死循環,不斷地從MessageQueue中抽取Message,Message經過綁定的內部target(handler類型),msg.target.dispatchMessage(msg)將該消息傳給對應的Handler接收。在dispatchMessage方法內調用handleCallback或handleMessage方法spa

ThreadLocal理解

建立Handler對象時,須要先爲這個Handler建立Looper.prepara( )新建一個looper對象。一個線程中只會有一個looper。由於looper使用ThreadLocal.set方法。在set方法中,會對應着當前Thread,將Looper存儲在其成員變量ThreadLocalMap中。其中key是ThreadLocal,value是looper。所以looper-threadLocal-Thread是一一對應關係。線程

實際上ThreadLocal的值是放入了當前線程的一個ThreadLocalMap實例中,因此只能在本線程中訪問,其餘線程沒法訪問。code

對象存放在哪裏

在Java中,棧內存歸屬於單個線程,每一個線程都會有一個棧內存,其存儲的變量只能在其所屬線程中可見,即棧內存能夠理解成線程的私有內存。而堆內存中的對象對全部線程可見。堆內存中的對象能夠被全部線程訪問。對象

###Handler發送和處理消息過程分析接口

Handler發送消息:Handler.sendMessage(Message message)

Handler處理信息:

new  Handler(){
        // 經過複寫handlerMessage()從而肯定更新UI的操做
        @Override
        public void handleMessage(Message msg) {
                ...// 需執行的UI操做
            }
    };

sendMessage方法將message 入隊messageQueue(單鏈表實現)在ActivityThread中會調用Looper.prepareMainLooper()生成looper,looper中會建立MessageQueue 。Looper.loop( )中有個死循環,不斷從messageQueue中取message。

public static void main(String[] args) {
    Looper.prepareMainLooper();
    long startSeq = 0;
    if (args != null) {
        for (int i = args.length - 1; i >= 0; --i) {
            if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                startSeq = Long.parseLong(
                        args[i].substring(PROC_START_SEQ_IDENT.length()));
            }
        }
    }
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

Looper類

private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}
public static void loop() {
        
        ...// 僅貼出關鍵代碼

        // 1. 獲取當前Looper的消息隊列
            final Looper me = myLooper();         
            final MessageQueue queue = me.mQueue;
            for (;;) {  
            Message msg = queue.next(); 
            if (msg == null) {
                return;
            }
            // next():取出消息隊列裏的消息
            // 若取出的消息爲空,則線程阻塞 

            // 2.2 派發消息到對應的Handler
            msg.target.dispatchMessage(msg);
            // 把消息Message派發給消息對象msg的target屬性
            // target屬性實際是1個handler對象
        // 3. 釋放消息佔據的資源
        msg.recycle();
        }
}

Handler中的dispatchMessage方法

public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}

今年金九銀十我花一個月的時間收錄整理了一套知識體系,若是有想法深刻的系統化的去學習的,能夠點擊傳送門,我會把我收錄整理的資料都送給你們,幫助你們更快的進階。

相關文章
相關標籤/搜索