http://blog.csdn.net/innost/article/details/47660591
http://blog.csdn.net/luoshengyang/article/details/6882903
安卓系統(tǒng)啟動(dòng)流程中读宙,SystemManagerService啟動(dòng)WindowManagerService負(fù)責(zé)窗口管理蓝谨,WindowManagerService啟動(dòng)InputManger負(fù)責(zé)鍵盤管理。
activity的啟動(dòng)過(guò)程中赚楚,ActivityThread中handleLaunchActivity調(diào)用performLaunchActivity加載完activity對(duì)象之后返回handleLaunchActivity方法,接著調(diào)用handleResumeActivity使activity進(jìn)駐resumed狀態(tài)。handleResumeActivity函數(shù)里ActivityThread將DecorView添加到WindowManagerImpl的mViews中,創(chuàng)建一個(gè)mViewRoot實(shí)例仅颇,Activity通過(guò)mViewRoot與WindowManagerService進(jìn)行消息傳遞,處理viewTree的各種事件碘举。
ViewRoot的setView方法干了三件事
- 將被激活的Activity窗口忘瓦,會(huì)通知InputManager,它是當(dāng)前激活的窗口引颈,因此耕皮,一旦發(fā)生鍵盤事件的時(shí)候境蜕,InputManager就把這個(gè)鍵盤事件拋給這個(gè)Activity處理;
- 應(yīng)用程序會(huì)為這個(gè)Activity窗口和InputManager之間創(chuàng)建一個(gè)鍵盤消息接收通道凌停,這個(gè)通道的一端由一個(gè)Server端的InputChannel構(gòu)成粱年,另一端由Client端的InputChannel構(gòu)成,Server端的InputChannel注冊(cè)在由InputManager所管理的InputDispatcher中罚拟,而Client端的InputChannel注冊(cè)在由應(yīng)用程序主線程的消息循環(huán)對(duì)象Looper中台诗;
- 注冊(cè)在InputDispatcher中的InputChannel由一個(gè)反向管道的讀端和一個(gè)前向管道的寫端組成,而注冊(cè)在應(yīng)用程序主線程的消息循環(huán)對(duì)象Looper中的InputChannel由這個(gè)前向管道的讀端和反向管道的寫端組成舟舒,這種交叉結(jié)構(gòu)使得當(dāng)有鍵盤事件發(fā)生時(shí)拉庶,InputDispatcher可以把這個(gè)事件通知給應(yīng)用程序。
應(yīng)用程序注冊(cè)好鍵盤消息接收通道后秃励,接下來(lái)就開始分析InputManager分發(fā)鍵盤消息給應(yīng)用程序的過(guò)程了。
- 鍵盤事件發(fā)生吉捶,InputManager中的InputReader被喚醒夺鲜,此前InputReader睡眠在/dev/input/event0這個(gè)設(shè)備文件上;
- InputReader被喚醒后呐舔,它接著喚醒InputManager中的InputDispatcher币励,此前InputDispatcher睡眠在InputManager所運(yùn)行的線程中的Looper對(duì)象里面的管道的讀端上;
- InputDispatcher被喚醒后珊拼,它接著喚醒應(yīng)用程序的主線程來(lái)處理這個(gè)鍵盤事件食呻,此前應(yīng)用程序的主線程睡眠在Client端InputChannel中的前向管道的讀端上;
- 應(yīng)用程序處理處理鍵盤事件之后澎现,它接著喚醒InputDispatcher來(lái)執(zhí)行善后工作仅胞,此前InputDispatcher睡眠在Server端InputChannel的反向管道的讀端上,注意這里與第二個(gè)線索處的區(qū)別剑辫。
當(dāng)Activity窗口創(chuàng)建時(shí)干旧,它會(huì)向InputManager注冊(cè)鍵盤消息接收通道,而當(dāng)Activity窗口銷毀時(shí)妹蔽,它就會(huì)向InputManager注銷前面注冊(cè)的鍵盤消息接收通道了椎眯。