Android事件分发机制一:事件是如何到达activity的? (2)

前面我们讲到,view树的根节点可以是一个viewGroup,也可以是一个单独的view,因此,这里的派发就会有两种不同的方式:直接给view进行处理 or viewGroup进行事件分发。viewGroup继承自view,view中有一个方法用于分发事件:dispatchTouchEvent 。子类可重写该方法来实现自己的分发逻辑,ViewGroup重写了该方法。

我们的应用布局界面或者dialog的布局界面,顶层的viewGroup为DecorView,因此会调用DecorView的 dispatchTouchEvent 方法进行分发。DecorView重写了该方法,逻辑比较简单,仅仅做了一个判断:

DecorView.java api29 public boolean dispatchTouchEvent(MotionEvent ev) { final Window.Callback cb = mWindow.getCallback(); return cb != null && !mWindow.isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev); }

如果window callBack对象不为空,则调用callBack对象的分发方法进行分发

如果window callBack对象为空,则调用父类ViewGroup的事件分发方法进行分发

而Activity实现了Window.CallBack接口,并在创建布局的时候,把自己设置给了DecorView,因此在Activity的布局界面中,DecorView会把事件分发给Activity进行处理。同理,在Dialog的布局界面中,会分发给实现了callBack接口的Dialog。

而如果顶层的viewGroup不是DecorView,那么对调用对应view的dispatchTouchEvent方法进行分发。例如,顶层的view是一个Button,那么会直接调用Button的 dispatchTouchEvent 方法;如果顶层viewGroup子类没有重写 dispatchTouchEvent 方法,那么会直接调用ViewGroup默认的 dispatchTouchEvent 方法。

整体的流程如下图:

viewRootImpl对事件的分发流程

viewRootImpl会直接调用管理的view的 dispatchTouchEvent 方法,根据具体的view的类型,调用具体的方法。

view树的根view可能是一个view,也可能是一个viewGroup,view会直接处理事件,而viewGroup则会进行分发。

DecorView重写了 dispatchTouchEvent 方法,会先判断是否存在callBack,优先调用callBack的方法,也就是把事件传递给了Activity。

其他的viewGroup子类会根据自身的逻辑进行事件分发。

因此,触摸事件一定是从Activity开始的吗?不是,Activity只是其中的一种情况,只有Activity自己负责的那一棵view树,才一定会到达activity,而其他的window,则不会经过Activity。触摸事件是从viewRootImpl开始,而不是Activity。

总结

最后我们对整个流程进行一次回顾:

整体流程

IMS从系统底层接收到事件之后,会从WMS中获取window信息,并将事件信息发送给对应的viewRootImpl

viewRootImpl接收到事件信息,封装成motionEvent对象后,发送给管理的view

view会根据自身的类型,对事件进行分发还是自己处理

顶层viewGroup一般是DecorView,DecorView会根据自身callBack的情况,选择调用callBack或者调用父类ViewGroup的方法

到这里,虽然触摸事件的“去脉”我们还不清楚,但是他的“来龙”就已经非常清晰了。后续Activity、Dialog等callBack,viewGroup,其他顶层ViewGroup对象如何对触摸事件进行处理,我将会在下一篇文章进行分析。

事件分发的来源远没有这么简单,源码的细节有非常多的内容值得我们去学习,而本文只是把整体的流程抽了出来。这里对于有兴趣读者推荐一本书:《深入理解android卷Ⅲ》。

感谢阅读,希望文章对你有帮助!

全文到此,原创不易,觉得有帮助可以点赞收藏评论转发。
笔者才疏学浅,有任何想法欢迎评论区交流指正。
如需转载请评论区或私信交流。

另外欢迎光临笔者的个人博客:传送门

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjgzz.html