Android事件分发机制

Posted zhouliweiblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android事件分发机制相关的知识,希望对你有一定的参考价值。

      今天coding,无意写了个小bug出来,dialog去dismiss的时候不起作用,后来排查到是在dispatchTouchEvent中去show dialog时,有可能会创建两个Dialog,然后监听回调还是第一个的,当dismiss的时候,mDocorView是null的,所以dismiss的时候,就直接return掉,没有执行dismiss的逻辑。总结来说这个bug还是因为自己对事件分发理解的不透彻,正好之前没总结过,所以就写一遍博客记录下,方便自己之后查看。

  首先我们直接把View和ViewGroup一起来看,写一个demo,demo很简单,自定义两个View:一个继承Button(TestEventBtn),一个继承LinearLayout(TestEventDispatchLayout),然后这个Button放到TestEventDispatchLayout上,网上大部分的例子应该都是这个做demo的吧。之后就分别实现他们的dispatchTouch、onTouchEvent、onInterceptTouchEvent(只有ViewGroup有)、另外在Activity中把两个控件的onClickListener也加上。

  1)首先我们来做做实验,通过实验肯定有些情况不明白的,再看代码。

  •  点击TestEventDispatchLayout除了TestEventBtn之外的区域:

技术图片

从上面的日志我们可以看出touch事件首先是在被点击到的区域传递。从Activity到TestEventDispatchLayout传递了ACTION_UP和ACTION_DOWN事件,最后被TestEventDispatchLayout的onClick把事件吃掉,我们改动下,不设置onClickListener看看会怎么样:

  • 点击TestEvent:

技术图片

  • 点击TestEventDispatchLayout之外的区域:

技术图片

上面三种情况都是从MainActivity 的dispatchTouchEvent开始的,我们可以debug抓个trace看下点击事件传递路径:

技术图片

从这个堆栈,我们大致可以看出,最下面应该是硬件层会不停的检测是否有touch事件,当有touch事件时,会通过InputEventReceiver去dispatchInputEvent,接着中间这一大块都是在ViewRootImpl中的处理。

基本都是对事件的处理和传递,最后会传递到PhoneWindow的DecorView中dispatchTouchEvent,它的源码是:

技术图片

熟悉代码的同学可能会对这个Callback特别熟悉,Activity就实现了这个callback,因此这里的Callback就是Activity,好了,这就验证了上面的都是从Activity的dispaTouchEvent开始了。

从网上找了一个哥们的图,如下,能比较直观的理解事件传递过程。

技术图片

一个View就像一棵树一样,touch事件从根依次的传递到叶子的view。这也是android设计巧妙的地方,用了组合设计模式。

2)

 

以上是关于Android事件分发机制的主要内容,如果未能解决你的问题,请参考以下文章

Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )

Android事件分发机制五:面试官你坐啊

Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 五 )

Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 三 )

Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 二 )

Android 事件分发事件分发源码分析 ( ViewGroup 事件传递机制 一 )