概述
InputManagerService構(gòu)造時(shí)會(huì)構(gòu)造naive的binder server inputManager。此處會(huì)創(chuàng)建inputReader和inputDispatcher兩條死循環(huán)線(xiàn)程。
inputReader利用inotify機(jī)制監(jiān)聽(tīng)/dev/input下的設(shè)備節(jié)點(diǎn)增刪(最終也是 通過(guò)將inotify創(chuàng)建的fd掛到epoll下實(shí)現(xiàn)的)液斜,獲取到新增的節(jié)點(diǎn)后,利用epoll監(jiān)聽(tīng)這些設(shè)備節(jié)點(diǎn)的rawEvent。
監(jiān)聽(tīng)到這些rawEvent后會(huì)通過(guò)xxxMapper將其加工為xxxArgs旗唁,再轉(zhuǎn)發(fā)給監(jiān)聽(tīng)者inputDispatcher畦浓。
inputDispatcher收到后只是做完簡(jiǎn)單的事件有效性判斷后就往mInboundQueue中塞。
inputDispatcher線(xiàn)程就是循環(huán)讀取mInboundQueue看是否有數(shù)據(jù)检疫,有數(shù)據(jù)則開(kāi)始分發(fā)讶请。分發(fā)時(shí)先找到事件可以派發(fā)的窗口,該過(guò)程會(huì)涉及anr的判斷屎媳,再將事件塞到connection.outboundqueue中夺溢,再通過(guò)socket傳給app,再將事件塞到waitQueue中烛谊,等app處理完事件回調(diào)過(guò)來(lái)再將waitQueue中的事件刪除风响。
代碼分析的入口在InputManagerService#start
一些重要的類(lèi)和概念
InputReader
https://blog.csdn.net/zhzhangnews/article/details/91490097
InputDispatcher
https://blog.csdn.net/zhzhangnews/article/details/106795348
InputDispatcher的實(shí)現(xiàn)主要涉及3個(gè)Queue: 1. InboundQueue: 這個(gè)隊(duì)列里面存儲(chǔ)的是從InputReader送來(lái)到輸入事件 2. OutboundQueue:這個(gè)隊(duì)列里面存儲(chǔ)的是即將要發(fā)送給應(yīng)用的輸入事件 3. WaitQueue:這個(gè)隊(duì)列里面存儲(chǔ)的是已經(jīng)發(fā)給應(yīng)用的事件,但應(yīng)用還未處理完成丹禀。(OutboundQueue和WaitQueue在存在于Connection中)
InputChannel:本質(zhì)上是一對(duì)SocketPair
ACTION_CANCEL
case1:
viewGroup中有一個(gè)btn状勤,在viewGroup中攔截第一次move事件。btn會(huì)收到一個(gè)CANCEL事件且不會(huì)收到后續(xù)事件.
如果某一個(gè)子View處理了Down事件(此時(shí) mFirstTouchTarget不為null)双泪,那么隨之而來(lái)的Move和Up事件也會(huì)交給它處理持搜。但是交給它處理之前,父View還是可以攔截事件的焙矛,如果攔截了事件葫盼,那么子View就會(huì)收到一個(gè)Cancel事件,并且不會(huì)收到后續(xù)的Move和Up事件
https://blog.csdn.net/cufelsd/article/details/89471402
case2:
正在往window1不斷派發(fā)事件如MOVE事件村斟,此時(shí)按home鍵贫导,window1會(huì)受到CANCEL事件。
原因:當(dāng)焦點(diǎn)窗口變化時(shí)surfaceFlinger會(huì)調(diào)用到InputDispatcher::setInputWindowsLocked