Android Handler 工作原理

2021-08-20 08:25:29 字數 3050 閱讀 4136

handler、message、messagequeue、looper

1.looper.prepare();

public static void 

prepare()

private static void

prepare(boolean quitallowed)

//這裡建立的looper

sthreadlocal.set(new looper(quitallowed));

}

private 

looper(boolean quitallowed)

平時我們在主線程和子執行緒之間切換沒呼叫looper.prepare();是因為activity建立的時候已經呼叫過looper.preparemainlooper();

2.looper.loop();

public static void loop() 

final messagequeue queue = me.mqueue;

//這裡是個死迴圈

for (;;)

//...此處省略**

try finally

} //...此處省略**

}}

3.message

好像沒啥說的,或者不知道怎麼說。。。。

while the constructor of message is public, the best way to get

* one of these is to call or one of the

* methods, which will pull

* them from a pool of recycled objects.

這裡是官方的注釋,官方建議使用message.obtain()方法來獲取message

4.new handler()

//最常用的構造方法

public handler()

public handler(callback callback, boolean async)

}mlooper = looper.mylooper();

if (mlooper == null)

mqueue = mlooper.mqueue;

mcallback = callback;

masynchronous = async;

}

5.handler.sendmessage()

//方法呼叫

public final boolean sendmessage(message msg)

public final boolean sendmessagedelayed(message msg, long delaymillis)

return sendmessageattime(msg, systemclock.uptimemillis() + delaymillis);

}public boolean sendmessageattime(message msg, long uptimemillis)

return enqueuemessage(queue, msg, uptimemillis);

}private boolean enqueuemessage(messagequeue queue, message msg, long uptimemillis)

//將訊息加入訊息佇列中

return queue.enqueuemessage(msg, uptimemillis);

}

以常用的子執行緒向主線程傳送訊息為例,梳理下邏輯

activity初始化時幫我們呼叫的了looper.prepare(),這裡建立了looper和messagequeue

activity初始化時也幫我們呼叫了looper.loop(),進入死迴圈一直在呼叫queue.next()獲取訊息

傳送訊息,最終通過queue.enqueuemessage(msg, uptimemillis);  將訊息加入訊息佇列中

死迴圈中獲取到剛剛傳送的訊息通過queue.next(); 方法獲取到訊息

獲取到訊息通過msg.target.dispatchmessage(msg);分發到handler

扯了半天,怎麼切換的執行緒?

這裡依靠的是threadlocal,簡單的說它只屬於自己的執行緒,即使是同乙個threadlocal物件,也可以在不同的執行緒中獲取到不同的值,想專門了解這個的可以自行查詢,這裡不做長篇敘述。

looper類中有

static final threadlocalsthreadlocal = new threadlocal();
在looper.perpare()中
sthreadlocal.set(new looper(quitallowed));
還是以子執行緒向主線程傳送訊息為例

此時的looper.perpare()和looper.loop()都還是在主線程也就是ui執行緒中被呼叫,因為是activity初始化時已經幫我們呼叫了looper.perpare()和looper.loop(),所以不需要我們手動呼叫了。

向主線程傳送訊息,所以我們的handler要建立在主線程裡,在上面hnadler的構造方法裡有

mlooper = looper.mylooper();

因為上述介紹到threadlocal的特性,同在主線程中,所以獲取到的即為在looper.perpare()中建立的looper物件

在子執行緒中傳送訊息出去,訊息被放入訊息佇列中,looper物件是相同的,而所使用的訊息佇列是looper物件的私有屬性,也沒有發生變化,所以messgequeue也是相同的,之在looper.loop()方法中傳送的訊息通過queue.next()方法被獲取到,在looper.loop()方法中呼叫了 msg.target.dispatchmessage(msg)方法,而looper.loop()方法是在主線程中呼叫的,所以最終handler中的dispatchmessage方法就是在主線程中呼叫的了。

Android Handler訊息機制

handler訊息機制 優點 寫法 1.主線程中建立乙個handler物件 handler handler new handler 2.複寫handler物件的handlermessage方法 public void handlemessage android.os.message msg 3.在子...

Android Handler相關問題

1 handler是什麼?答 handler是更新ui介面的機制,也是訊息處理的機制,我們可以傳送訊息,也可以處理訊息 2 為什麼要有handler?答 android在設計的時候,封裝了一套訊息建立 傳遞 處理機制,如果不遵循這樣的機制就沒辦法更新ui資訊,就會丟擲異常。3 handler怎麼用?...

android handler呼叫post方法阻塞

1.試下用postdelayed runnable a,int time 因為post把訊息放到looper中就返回,但looper中沒有其他訊息又會被立刻取出來執行,這樣就有可能做了run中的操作,而沒有及時重新整理按鈕.2.另外,這種做法耗時操作仍然是由ui執行緒去做了。而不是你想的另起了執行緒...