概述
前文已經決議的內容是:app行程在接收到input事件后,最終傳遞到View,經過了哪些操作,
前文地址:由淺入深學習android input系統(一) - input事件如何傳遞到View
本文將繼續探索 android input系統,分析下系統行程是怎么將input事件傳遞到app行程的,
InputDispatcher的事件分發
系統行程的input事件都通過InputDispatcher這個類來進行分發,比如當有觸摸事件發送過來時,InputDispatcher會對其進行判斷來分發給哪個行程,哪個window,
呼叫任務堆疊如下:
- InputDispatcher.dispatchOnce()
- InputDispatcher.dispatchOnceInnerLocked()
- InputDispatcher.dispatchKeyLocked()
- InputDispatcher.dispatchEventLocked()
- InputDispatcher.prepareDispatchCycleLocked()
- InputDispatcher.enqueueDispatchEntriesLocked()
- InputDispatcher.startDispatchCycleLocked()
- InputPublisher.publishKeyEvent()
- InputChannel.sendMessage()
邏輯如下:
- InputDispatcher的執行緒通過回圈執行dispatchOnce()方法來接收事件,
- dispatchOnceInnerLocked()方法中會去判斷此次事件是否有效,以及是否需要ANR等,
- dispatchKeyLocked()會去查找當前的視窗,如果找到了視窗,并且事件可以傳遞就會繼續往下走,
- dispatchEventLocked()中會獲取當前的inputChannel,然后將其傳入到prepareDispatchCycleLocked()方法中,
- prepareDispatchCycleLocked()方法會判斷當前的inputChannel是否鏈接正常,如果不正常就會直接回傳,如果很正常就會邏輯繼續走,
- enqueueDispatchEntriesLocked()會根據分發事件的型別,進行不同的處理后,放入到outboundQueue這個佇列中,然后執行后續邏輯,
- startDispatchCycleLocked()會從outboundQueue佇列中取出已經處理好的事件,通過InputPublisher.publishKeyEvent()將事件發出去,
- publishKeyEvent()收到事件后通過InputChannel.sendMessage()將事件發送給app行程中對應的ViewRootImpl,
繼續探索
留兩個疑問后文探索,有興趣的讀者可以持續關注,或者自行閱讀下原始碼:
- input事件是怎么從硬體上獲取到的?
- InputDispatcher是什么時候初始化的?
- InputChannel是什么時候初始化的?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/286408.html
標籤:其他
