Android消息機(jī)制及其原理
Handle的原理
andriod提供了Handler和Looper來(lái)滿足線程間的通信鉴扫。Handler先進(jìn)先出原則。Looper類用來(lái)管理特定線程內(nèi)對(duì)象之間的消息交換(MessageExchange)纹蝴。
MessageQueue
MessageQueue是持有Message(在Looper中派發(fā))的一個(gè)鏈表珊蟀,Message并不是直接添加到MessageQueue中的嫉入,而是通過(guò)與Looper相關(guān)聯(lián)的Handler來(lái)進(jìn)行的丹喻。
用來(lái)存放線程放入的消息,讀取會(huì)自動(dòng)刪除消息,單鏈表維護(hù)碌奉,在插入和刪除上有優(yōu)勢(shì)短曾。在其next()中會(huì)無(wú)限循環(huán),不斷判斷是否有消息赐劣,有就返回這條消息并移除嫉拐。
Looper
一個(gè)線程可以產(chǎn)生一個(gè)Looper對(duì)象,由它來(lái)管理此線程里的MessageQueue
Looper創(chuàng)建的時(shí)候會(huì)創(chuàng)建一個(gè)MessageQueue魁兼,調(diào)用loop()方法的時(shí)候消息循環(huán)開(kāi)始婉徘,loop()也是一個(gè)死循環(huán),會(huì)不斷調(diào)用messageQueue的next(),當(dāng)有消息就處理盖呼,否則阻塞在messageQueue的next()中儒鹿。當(dāng)Looper的quit()被調(diào)用的時(shí)候會(huì)調(diào)用messageQueue的quit(),此時(shí)next()會(huì)返回null,然后loop()方法也跟著退出几晤。
MessageQueue和Looper是一對(duì)一關(guān)系约炎,Handler和Looper是多對(duì)一
Handler
在主線程構(gòu)造一個(gè)Handler,與Looper溝通蟹瘾,以便push新消息到MessageQueue里;
接收Looper從MessageQueue取出Handler所送來(lái)的消息圾浅。然后在其他線程調(diào)用sendMessage(),此時(shí)主線程的MessageQueue中會(huì)插入一條message,然后被Looper使用.
Thread
UIthread 通常就是main thread憾朴,而Android啟動(dòng)程序時(shí)會(huì)替它建立一個(gè)MessageQueue,系統(tǒng)的主線程在ActivityThread的main()為入口開(kāi)啟主線程狸捕,其中定義了一系列消息類型,包含四大組件的啟動(dòng)停止众雷。
消息隊(duì)列分發(fā)算法源碼
每個(gè)message之間拉手灸拍,知道自己前面和后面的message
message通過(guò)時(shí)間戳來(lái)排序,小的在前
配合handle取出message砾省,message時(shí)間到鸡岗,就去除隊(duì)列首個(gè)message,取出之后置為null纯蛾,第二個(gè)message就排在第一纤房,類推
//消息的存放
boolean enqueueMessage(Message msg, long when) {
? ? synchronized (this) {
? ? ? ? msg.when = when;
? ? ? ? Message p = mMessages;? //注解1
? ? ? ? if (p == null || when == 0 || when < p.when){
? ? ? ? ? ? msg.next = p;
? ? ? ? ? ? mMessages = msg;? ? //注解2
? ? ? ? } else {
? ? ? ? ? ? Message prev;
? ? ? ? ? ? for (;;) {? ? ? ? ? //注解3
? ? ? ? ? ? ? ? prev = p;
? ? ? ? ? ? ? ? p = p.next;
? ? ? ? ? ? ? ? if (p == null || when < p.when) {
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? msg.next = p;
? ? ? ? ? ? prev.next = msg;
? ? ? ? }
? ? }
? ? return true;
}