Android点击事件分发流程
一、Native层主要包含InputReader线程和InputDispatcher线程都是通过Looper循环不停监听和处理点击事件。InputReader线程使用EventHub的getEvents获取点击事件。EventHub通过监听系统的/dev/input节点实现。使用了epoll机制InputReader和InputDispatcher各自都有点击事件的队列存储点击事件。点击事件收到后需要在Native层寻找目标窗口然后直接通过JNI派发到应用进程。二、ViewRootImpl层android.view.ViewRootImpl.WindowInputEventReceiver#onInputEvent是Java层处理函数。一个点击事件会经过很多的android.view.ViewRootImpl.InputStage进行处理采用了责任链设计模式其中TouchEvent使用ViewPreImeInputStage处理。三、分发过程首先分发到Activity的dispatchTouchEvent然后通过PhoneWindow透传到跟View也就是DecorView。DecorView本身是ViewGroup类型通过dispatchTouchEvent进行分发。首先onInterceptTouchEvent判断ViewGroup本身是否拦截事件如果不拦截然后遍历所有的子View进行分发。如果子View消费点击事件那么就结束流程。如果所有的子View均没有消费点击事件那么ViewGroup自己的dispatchTouchEvent函数尝试消费点击事件。如果根DecorView都没有消费点击事件那么Activity通过onTouchEvent尝试消费点击事件。四、View的时序说明dispatchTouchEvent中首先调用android.view.View.OnTouchListener#onTouch。然后是View本身的android.view.View#onTouchEvent方法android.view.View#onTouchEvent首先尝试android.view.View#mTouchDelegate代理对象消费点击事件。android.view.View.OnClickListener回调是最后收到的。并且是action_up之后才会收到click回调。五、时序图右键在浏览器新的标签页中打开看完整时序图参考InputDispatcher线程https://gityuan.com/2016/12/17/input-dispatcher/InputReader线程https://gityuan.com/2016/12/11/input-reader/