Handleroop
這裏簡化一下代碼 以便理解post
Handler不必定要在主線程建 但如Handler handler = new Handler(); 會使用當前的Looper的,
因爲要更新UI 因此最好在主線程this
new Handler()
{
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
}spa
myLooper();會要求 先調用 Looper.prepare().net
private static void prepare() { //實際上就初臺化一個實現
sThreadLocal.set(new Looper()); //也就是說 線程和Looper是綁定的
}
sThreadLocal能夠直接取得自身的實例
//再來看handler.sendMessage 發送消息
public final boolean sendMessage(Message msg)
{
msg.target = this; //把目標設爲handler自身 這樣就能夠調用自身的handlerMessage
mQueue.enqueueMessage(msg, uptimeMillis); //插入到消息隊列中
}
取消息
public static void loop() 注意這是靜態的
{
Looper me = myLooper()
for (;;) {
//從消息隊列中不斷取出消息
Message msg = me.mQueue.next();
msg.target.dispatchMessage(msg);
}
}
個線程裏面只能有一個Looper,而一個Looper對應着一個MessageQueue。因此在一個線程裏面,不管你有多少個Handler,最終發送的消息都要在同一個MessageQueue中排隊等待被執行。線程
來看看handler的dispatchMessage
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg); //這個是用來執行handler.post() 因此重載 handlerMessage不會管post過來的回調
}
handleMessage(msg); //就回調回去了
}
}blog
具體能夠看https://blog.csdn.net/fnhfire_7030/article/details/79518819 這個講得很細
隊列
在工做線程中執行耗時任務,當任務完成時,會返回UI線程,通常是更新UI。這時有兩種方法能夠達到目的。get
一種是handler.sendMessage。發一個消息,再根據消息,執行相關任務代碼。消息隊列
另外一種是handler.post(r)。r是要執行的任務代碼。意思就是說r的代碼實際是在UI線程執行的。能夠寫更新UI的代碼。
緣由 能夠看這個 https://blog.csdn.net/yypblog/article/details/17734425