Input框架
每增加一個WindowState.java,WMS都會通過registerInputChannel向InputDispatcher注冊一個connection,這個connection用于后續(xù)event查找當前的觸摸位置屬于哪一個window
event 主要通過兩種途徑返回到framework
1帐姻、key發(fā)往PhoneWindowManager
-
一路通過InputMonitor(繼承于WindowManagerCallbacks)傳給PhoneWindowManager來做系統(tǒng)輸入事件的處理奶段,核心回調(diào)函數(shù)interceptKeyBeforeQueueing
圖片.png
2、motion發(fā)往window
- 另一方面通過InputDispatcher中的socket將這些事件傳給焦點及監(jiān)視窗口(ViewRootImpl)扛伍,然后會調(diào)用相應View的onTouchEvent词裤,核心是publishKeyEvent/publishMotionEvent
-
InputDispatcher會維護和WMS中所有窗口的連接,雖然一般只會往焦點窗口發(fā)事件逆航。
ViewRootImpl中維護了pending input event的列表,用mPendingInputEventHead和mPendingInputEventTail指示拇惋,其中的元素為QueuedInputEvent類型抹剩。當consumeBatchedInputEvents調(diào)用后,會
回調(diào)enqueueInputEvent()加入event元素澳眷,然后ViewRootImpl延時或非延時在doProcessInputEvents()中讀出并處理。
總結(jié)
Input系統(tǒng)—InputReader線程:通過EventHub從/dev/input節(jié)點獲取事件衷敌,轉(zhuǎn)換成EventEntry事件加入到InputDispatcher的mInboundQueue拓瞪。
-
Input系統(tǒng)—InputDispatcher線程:從mInboundQueue隊列取出事件,轉(zhuǎn)換成DispatchEntry事件加入到connection的outboundQueue隊列面氓。再然后開始處理分發(fā)事件蛆橡,取出outbound隊列(開始像view分發(fā)事件),同時在分發(fā)開始的是否將此事件放入waitQueue中航罗,以便當view中事件處理完成回調(diào)到InputDispatcher中時粥血,能找到對應的事件。
- 每次dispatch motion 之前都要檢查接收者的狀態(tài)复亏。如果上一個event沒有返回或者超時,則不會再次dispatch抬闷,而是等待。
-
Input系統(tǒng)—UI線程:創(chuàng)建socket pair笤成,分別位于”InputDispatcher”線程和focused窗口所在進程的UI主線程,可相互通信纵诞。
UI主線程:通過setFdEvents()培遵, 監(jiān)聽socket客戶端,收到消息后回調(diào)NativeInputEventReceiver();
“InputDispatcher”線程: 通過IMS.registerInputChannel()嗡呼,監(jiān)聽socket服務端皇耗,收到消息后回調(diào)handleReceiveCallback;