Android 輸入系統(tǒng)簡介

輸入事件的源頭位于/dev/input/下的設(shè)備節(jié)點,輸入事件的終點是WMS管理的某個窗口。所以輸入系統(tǒng)的主要工作是讀取設(shè)備節(jié)點中的原始事件,接著進行加工封裝,然后派發(fā)給一個特定的窗口或者窗口中的控件。整個流程由InputManagerService系統(tǒng)服務(wù)為核心的多個參與者共同完成,如下圖所示。


輸入系統(tǒng)簡介.png

流程大致為:

  1. 內(nèi)核將原始事件寫入設(shè)備節(jié)點
  2. InputReader不斷地通過EventHub將原始事件取出來并翻譯加工成Android輸入事件,然后交給InputDispather
  3. InputDispather根據(jù)WMS提供的窗口信息將事件交給合適的窗口
  4. 窗口的ViewRootImpl對象再沿著控件樹將事件派發(fā)給感興趣的控件
  5. 控件對齊收到的事件做出響應(yīng),更新自己的畫面、執(zhí)行特定的動作

下面介紹下參與者:

  1. Linux內(nèi)核:
    接收輸入設(shè)備的中斷,將原始事件的數(shù)據(jù)寫入設(shè)備節(jié)點中。
  2. 設(shè)備節(jié)點:
    內(nèi)核與IMS的橋梁,它將原始事件暴露給用戶空間,以便IMS可以從中讀取事件。
  3. InputManagerService:
    一個Android的系統(tǒng)服務(wù),分為Java層和Native層。
    Java層負責(zé)與WMS通信。
    Native層則是InputReader和InputDispatcher兩個輸入系統(tǒng)關(guān)鍵組件的運行容器。
  4. EventHub:
    通過getevents訪問設(shè)備節(jié)點,并把訪問到的原始輸入事件以及設(shè)備節(jié)點的增刪返回給使用者。
  5. InputReader:
    運行在一個獨立的線程中。通過線程循環(huán)不斷的從EventHub中讀取原始事件,然后進行加工處理封裝為包含更多信息、更具可讀性的輸入事件,然后交給InputDispatcher進行派發(fā)。
    當設(shè)備節(jié)點有增刪時,更新輸入設(shè)備列表和配置。
  6. InputReaderPolicy:
    為InputReader加工處理原始事件,提供策略配置信息。例如:鍵盤布局。
  7. InputDispatcher:
    運行在一個獨立的線程中。保管來自WMS的所有窗口的信息,其收到來自InputReader的輸入事件后,會在其保管的窗口中尋找合適的窗口,并將事件派發(fā)給此窗口。
  8. InputDispatcherPolicy:
    為InputDispatcher派發(fā)過程提供策略。例如截取某些特定的輸入事件用作特殊用途,或者阻止將某些事件派發(fā)給目標窗口。
    示例:截取HOME鍵到PhoneWindowManager中進行處理,阻止窗口收到HOME鍵按下的事件。
  9. WMS:
    當新建窗口時,WMS為新窗口和IMS創(chuàng)建了事件傳遞所用的通道。
    WMS實時更新窗口的可點擊區(qū)域、焦點窗口等信息給IMS的InputDispatcher。
  10. ViewRootImpl:
    對某些窗口,如壁紙窗口、SurfaceView的窗口來說,窗口就是輸入事件派發(fā)的終點。而其他的,比如說Activity、對話框等使用了Android控件系統(tǒng)的窗口來說,輸入事件的終點是控件(View)。ViewRootImpl將窗口所接收的輸入事件沿著控件樹將事件派發(fā)給感興趣的控件。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容