【Android】ANR是如何产生的?
2021-12-24 本文已影响0人
littlefogcat
众所周知,Android的输入事件是通过InputReader
监听系统dev/input
下的文件来获取输入事件,并由InputDispatcher
来进行分发的。
而ANR事件就是在InputDispatcher中产生的。
一、InputDispatcher
1. InputDispatcherThread
InputDispatcher
内部维护了一个线程InputDispatcherThread
,输入事件在这个线程中进行处理。这个线程在InputManager
中进行创建和启动。
它只做了一件事,就是无限调用dispatchOnce()
进行事件分发。
2. dispatchOnce 和 dispatchOnceInnerLocked
dispatchOnce()
会调用dispatchOnceInnerLocked()
进行事件分发,而如果判断出当前事件是触摸事件,则会又调用dispatchMotionLocked()
来分发触摸事件。在处理结束之后,会阻塞直到下一次事件的到来。
3. dispatchMotionLocked 和 findTouchedWindowTargetsLocked
dispatchMotionLocked()
会调用findTouchedWindowTargetsLocked()
查找触摸事件对应窗口目标并进行分发。如果当前窗口尚有未处理完的事件,则会调用handleTargetsNotReadyLocked
处理。
4. handleTargetsNotReadyLocked
handleTargetsNotReadyLocked
会判断目标事件等待时间,如果其大于5秒,则会调用onANRLocked
进入ANR流程。
以上便是ANR的产生过程。
二、总结
ANR的产生有两个必要条件:
- 至少需要两个事件;
- 在第二个事件到来的时候,第一个事件尚未处理完毕,并且处理时间超过5秒。
三、参考资料:
/frameworks/native/services/inputflinger/InputDispatcher.cpp
Android输入事件分发与拦截