1. 乙個執行緒裡面只有乙個looper。
2. 子執行緒也可建立handler。
前後需分別加上looper.prepare();和looper.loop();
標準寫法:
looper.prepare();
handler mhandler =
newhandler()
}};looper.loop();
在prepare 中建立looper。
3. 主線程對應的方法在activitythread的main方法中。
4. looper的構造方法中初始化了乙個messagequeue物件
private
looper
(boolean
quitallowed)
總:looper.prepare()方法初始話了乙個looper物件並關聯在乙個messagequeue物件,並且乙個執行緒中只有乙個looper物件,只有乙個messagequeue物件。而handler的構造方法則在handler內部維護了當前執行緒的looper物件
5. handler.sendmessage(msg) 會呼叫queue.enqueuemessage(msg, uptimemillis);,會發現 messagequeue並沒有使用列表將所有的message儲存起來,而是使用message.next儲存下乙個message,從而按照時間將所有的message排序;
6. looper.loop()
可以看到looper.loop()方法裡起了乙個死迴圈,不斷的判斷messagequeue中的訊息是否為空,如果為空則直接return掉,然後執行queue.next()方法
可以看到其大概的實現邏輯就是message的出棧操作,裡面可能對執行緒,併發控制做了一些限制等。獲取到棧頂的message物件之後開始執行:
msg.target
.dispatchmessage
(msg);
handle的dispatchmessage()
/**
* handle system messages here. */
public
void
dispatchmessage
(message msg)
else}
handlemessage(msg);}}
可以看到,如果我們設定了callback(runnable物件)的話,則會直接呼叫handlecallback方法:
private
static
void
handlecallback
(message message)
msg.callback為空的話,會直接呼叫我們的mcallback.handlemessage(msg),即handler的handlermessage方法。由於handler物件是在主線程中建立的,所以handler的handlermessage方法的執行也會在主線程中
原作者的總結:
1)主線程中定義handler,直接執行:
handler mhandler =
newhandler() };
而如果想要在子執行緒中定義handler,則標準的寫法為:
// 初始化該執行緒looper,messagequeue,執行且只能執行一次
looper.prepare();
// 初始化handler物件,內部關聯looper物件
handler mhandler =
newhandler() };
// 啟動訊息佇列出棧死迴圈
looper.loop();
2)乙個執行緒中只存在乙個looper物件,只存在乙個messagequeue物件,可以存在n個handler物件,handler物件內部關聯了本執行緒中唯一的looper物件,looper物件內部關聯著唯一的乙個messagequeue物件。
3)messagequeue訊息佇列不是通過列表儲存訊息(message)列表的,而是通過message物件的next屬性關聯下乙個message從而實現列表的功能,同時所有的訊息都是按時間排序的。
5)activity內部預設存在乙個handler的成員變數,android中一些其他的非同步訊息機制的實現方法:
handler的post方法:
mhandler.post(
newrunnable()
});檢視其內部實現:
public
final
boolean
post
(runnable r)
可以發現其內部呼叫就是sendmessage系列方法。。。
view的post方法:
public
boolean
post
(runnable action)
// assume that post will succeed later
viewrootimpl.getrunqueue().post(action);
return
true;
} 可以發現其呼叫的就是activity中預設儲存的handler物件的post方法。
activity的runonuithread方法:
public
final
void
runonuithread
(runnable action)
else }
判斷當前執行緒是否是ui執行緒,如果不是,則呼叫handler的post方法,否則直接執行run方法。
非同步訊息機制的理解
1 looper準備工作場地 sthreadlocal 和工作用的道具 messagequeue 2 handler可以理解為 該機制的外掛程式,在activity中,因為activitythread已經定義了looper,所以直接例項化hander就可以使用了 3 messagequeue是系統中...
非同步訊息處理機制
借鑑 為什麼不能在子執行緒更新ui?1 ui是非執行緒安全的,主線程和子執行緒同時更新ui的話會導致錯誤,如ui錯亂之類的。2 ui更新是很耗效能的,更別說為了執行緒安全加鎖了,最簡單的方法就是更新ui的操作放到乙個執行緒中,即主線程 handler機制 looper 維持乙個thread物件以及m...
非同步訊息處理機制
因為android不允許在子執行緒中進行更新ui,非同步訊息處理機制來解決這個問題。android中的非同步訊息處理由4部分組成 message,handler,messagequeue和looper。message 傳遞訊息 handle 傳送,處理資訊 messagequeue 訊息隊裡,存放h...