在此之前,我们都知道,Android点击事件的分发顺序是:
Avtivity->PhoneWindow->DecorView->ViewGroup->View。
现在我们来讨论Android事件从哪里来的?
1. ActivityThread.performLaunchActivity() 中调用 Activity.attach(),创建PhoneWindow,PhoneWindow创建DecorView。
2. ActivityThread.handleResumeActivity()中调用Activity.makeVisible(),初始化WindowManager并调用WindowManager.addView()
3. 因为WindowManager是接口,找到其实现类并调用WindowManagerImpl.addView()。
4. 调用WindowManagerGlobal.addView(View view, ..., Window parentWindow, ...) ⚠️ 此时需要注意view为DecorView对象,该对象是通过ActivityThread.handleResumeActivity()中的PhoneWindow.getDecorView()获取,并直接赋值给Activity变量的。
5. WindowManagerGlobal.addView()创建了ViewRootImpl,并调用了ViewRootImpl.setView(view,...,...)
6. 连带创建InputChannel,InputQueue以及WindowInputEventReceiver对象并传入InputChannel和Looper
7. 其实Android事件的源头来自于用户输入行为,由硬件进行捕获,一般会保存在dev/input节点下,后续组装成KeyEvent/MotionEvent对象,经Native进入Java的InputEventReceiver.dispatchInputEvent()中。
8. ViewRootImpl.WindowInputEventReceiver extends InputEventReceiver,连带调用了enqueueInputEvent()->doProcessInputEvents-> deliverInputEvent(q),方法中获取到mFirstPostImeInputStage对象其实为ViewPostImeInputStage。
9. ViewPostImeInputStage extends InputStage 因此执行onProcess(),判断如果是触摸事件,调用processPointerEvent(),然后内部调用mView.dispatchPointerEvent(),此时的mView为DecorView,辗转调用到了DecorView.dispatchTouchEvent()
10. 通过 mWindow.getCallback()获取Window.Callback然后调用Window.Callback.dispatchTouchEvent(),这个Callback就是PhoneWindow里的mCallback,而mCallback则是Activity的attach()赋值的,此处也就自然调用到了Activity中,后续就是我们都知道的事件分发了,一个完整的闭环就结束了。
后续流程我们都知道了:
Activity的dispathcTouchEvent中调用了getWindow().superDispatchTouchEvent(ev):即是调用的PhoneWindow. superDispatchTouchEvent(ev)
PhoneWindow调用mDecor.superDispatchTouchEvent(event): 即是调用DecorView.superDispatchTouchEvent(event);
因为DecorView extends FrameLayout,FrameLayout extends ViewGroup,因此调用ViewGroup.dispatchTouchEvent(),通过连带调用ViewGroup.dispatchTransformedTouchEvent() 调用super.dispatchTouchEvent(event)
因为ViewGroup extends View, 因此会调用View.dispatchTouchEvent()事件又传递到了View,整个流程也就完整。