handler、message、messagequeue、looper
1.looper.prepare();
public static voidprepare()
private static void
prepare(boolean quitallowed)
//這裡建立的looper
sthreadlocal.set(new looper(quitallowed));
}
private平時我們在主線程和子執行緒之間切換沒呼叫looper.prepare();是因為activity建立的時候已經呼叫過looper.preparemainlooper();looper(boolean quitallowed)
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這裡是官方的注釋,官方建議使用message.obtain()方法來獲取message* one of these is to call or one of the
* methods, which will pull
* them from a pool of recycled objects.
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執行緒去做了。而不是你想的另起了執行緒...