ThreadLocal的工作原理
所操作的對象都是當(dāng)前線程的localValues對象的table數(shù)組表窘,因此在不同線程中訪問同一個ThreadLocal的set和get方法,他們所做的讀寫操作僅限于各自線程的內(nèi)部城看,這就是為什么ThreadLocal可以在多個線程中互不干擾的存儲和修改數(shù)據(jù),理解ThreadLocal的實現(xiàn)方式由于與理解Looper的工作原理
10.2.2 消息隊列的工作原理
消息隊列在Android中指的是MessageQueue杏慰,MessageQueue主要包含兩個操作:插入和讀取测柠。讀取操作本身會伴隨著刪除操作,插入和讀取對應(yīng)的方法分別是enqueueMessage和next缘滥,其中enqueueMessage的作用是往消息隊列中插入一條消息轰胁,而next的作用是從消息隊列中取出一條消息并將它從消息隊列中移除,盡管messageQueue叫做消息隊列朝扼,但是他的內(nèi)部實現(xiàn)并不是用的隊列赃阀,而是單鏈表,單鏈表在插入和刪除上比較有優(yōu)勢擎颖。
從enqueueMessage中的實現(xiàn)來看榛斯,他的主要操作其實就是單鏈表的插入操作。
next方法是一個無限循環(huán)的方法肠仪,如果消息隊列沒有消息,那么next方法會一直阻塞在這個备典,那么當(dāng)新消息到來時异旧,next方法會返回這條消息并將其從單鏈表中移除
10.2.3 Looper的工作原理
Looper的loop方法的工作過程比較好理解,loop方法是一個死循環(huán)提佣,唯一跳出循環(huán)的方式是MessageQueue的next方法返回了null吮蛹。當(dāng)Looper的quit方法被調(diào)用時荤崇,Looper會調(diào)用MessageQueue的quite或者quitSafeley方法來通知消息隊列退出,當(dāng)消息隊列被標(biāo)記為退出狀態(tài)時潮针,他的next方法會返回null术荤。也就是說,Looper必須退出每篷,否則Loop方法就會無限循環(huán)下去瓣戚。loop方法會調(diào)用MessageQueue的next方法獲取新消息,而next是一個阻塞操作焦读,當(dāng)沒有消息時子库,next方法會一直阻塞在哪里,這也導(dǎo)致loop方法一直阻塞在哪里矗晃。如果MessageQueue的next方法返回了新消息仑嗅,Looper就會處理這條消息:msg.target.dispatchMessage(msg),這里的msg.target是發(fā)送這條消息的handler對象。這樣handler發(fā)送的消息最終又交給了它的dispatchMessage方法來處理了张症。但是這里不同的是仓技,Handler的dispatchMessage方法是在創(chuàng)建handler時所使用的Looper中執(zhí)行的。這樣就成功的將代碼切換到了指定的線程中去了
10.2.4 Handler的工作原理
Handler發(fā)送消息的過程僅僅是像消息隊列中插入了一條信息俗他,MessageQueue的next方法就會返回這條消息給Looper脖捻,Looper收到消息后就開始處理了。最終消息由Looper交由給handler處理拯辙,既handler的dispatchMessage方法會被調(diào)用郭变,這時候handler就會進入了處理消息的階段。
handler的處理消息的過程如下:
首先檢查message的callback是否為null,不為null就通過handleCallback來處理消息涯保。Message的callback是一個Runnable對象诉濒,實際上就是Handler的post方法所傳遞的Runnable參數(shù)。其次檢查mCallback是否為null夕春,不為null就調(diào)用mCallback的handleMessage方法來處理消息未荒。最后調(diào)用handler的handleMessage方法來處理消息。
10.3主線程的消息輪詢
android的主線程就是ActivityThread及志,主線程的入口方法為main片排,在main方法中系統(tǒng)會通過Looper.preparemainLooper()來創(chuàng)建主線程的Looper以及MessageQueue,并通過Looper.loop()來開啟主線程的消息循環(huán)速侈。
主線程的消息循環(huán)開始了以后率寡,ActivityThread還需要一個handler和消息隊列進行交互,這個handler就是ActivityThread.H ,他內(nèi)部定義了一組消息類型倚搬,主要包含了四大組件的啟動和停止等過程
ActivityThread通過ApplicationThread和AMS進行進程間通信冶共,AMS以進程間通信的方式完成ActivityThread的請求后會回調(diào)ApplicationThread中的Binder方法,然后ApplicationThread會像H發(fā)送消息,H收到消息后會將ApplicationThread中的邏輯切換到ActivityThread中去執(zhí)行捅僵,既切換到主線程中去執(zhí)行家卖,這個過程是主線程的消息循環(huán)模型。