眾所周知漾月,Android的輸入事件是通過InputReader
監(jiān)聽系統(tǒng)dev/input
下的文件來獲取輸入事件病梢,并由InputDispatcher
來進(jìn)行分發(fā)的。
而ANR事件就是在InputDispatcher中產(chǎn)生的栅屏。
一、InputDispatcher
1. InputDispatcherThread
InputDispatcher
內(nèi)部維護(hù)了一個線程InputDispatcherThread
堂鲜,輸入事件在這個線程中進(jìn)行處理栈雳。這個線程在InputManager
中進(jìn)行創(chuàng)建和啟動。
它只做了一件事缔莲,就是無限調(diào)用dispatchOnce()
進(jìn)行事件分發(fā)哥纫。
2. dispatchOnce 和 dispatchOnceInnerLocked
dispatchOnce()
會調(diào)用dispatchOnceInnerLocked()
進(jìn)行事件分發(fā),而如果判斷出當(dāng)前事件是觸摸事件痴奏,則會又調(diào)用dispatchMotionLocked()
來分發(fā)觸摸事件蛀骇。在處理結(jié)束之后,會阻塞直到下一次事件的到來读拆。
3. dispatchMotionLocked 和 findTouchedWindowTargetsLocked
dispatchMotionLocked()
會調(diào)用findTouchedWindowTargetsLocked()
查找觸摸事件對應(yīng)窗口目標(biāo)并進(jìn)行分發(fā)擅憔。如果當(dāng)前窗口尚有未處理完的事件,則會調(diào)用handleTargetsNotReadyLocked
處理檐晕。
4. handleTargetsNotReadyLocked
handleTargetsNotReadyLocked
會判斷目標(biāo)事件等待時間暑诸,如果其大于5秒,則會調(diào)用onANRLocked
進(jìn)入ANR流程辟灰。
以上便是ANR的產(chǎn)生過程个榕。
二、總結(jié)
ANR的產(chǎn)生有兩個必要條件:
- 至少需要兩個事件芥喇;
- 在第二個事件到來的時候西采,第一個事件尚未處理完畢,并且處理時間超過5秒继控。
三械馆、參考資料:
/frameworks/native/services/inputflinger/InputDispatcher.cpp
Android輸入事件分發(fā)與攔截