欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅谈android应用之事件分发

程序员文章站 2022-05-14 17:54:13
...

1. 前言

在android中,事件有多种种类,比如说最常见的屏幕的点击事件,除此之外,还有外接设备的信号事件,如鼠标,键盘,遥控器的信号事件。这里就拿最常见的屏幕的点击事件来说事。点击屏幕的时候,首先是硬件驱动采集点击屏幕时候的信息,硬件驱动采集到了之后,它本身不会做消费这些数据信息,它会往native层抛出这些信息,但最终native层会将这些信息再抛往上层framework层进行处理。这个过程可以研究系统服务IMS,这里不再详述。

到这一步,就到了我们通常所述的事件分发,即应用层的事件分发的过程。

2. 流程图

以下是事件分发的流程图,先大体看看在应用层事件分发与事件被消费的过程:
浅谈android应用之事件分发
可以看出整个流程呈现出U型状,可以大体总结出事件是往下分发,往上消费,接下来将对这个过程进行详细分析。

3. Activity

点击事件在应用层首先到Activity上,所以我们从Activity的分发方法看:

=============/frameworks/base/core/java/android/app/Activity.java ===============

    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

1.如果是down,说明是一个新的事件,初始化UI(空实现方法,没有太大实际意义)

2.调用PhoneWindow的superDispatchTouchEvent 方法,把事件从Activity 分发到PhoneWindows,再到DecorView,再到ViewGroup,View,如果中间不被中断拦截的正常情况下。(这个过程是事件分发核心方法,这个可以结合我的文章视图原理辅助理解)如果子View没有消费该事件,则调用自身的onTouchEvent尝试处理。

3.如果上面分发过程都没有消费事件,则最终由Activity的onTouchEvent方法消费事件。

4. ViewGroup

ViewGroup的分发方法主要作用是确定那个View消费事件

1.判断是否进行事件拦截,

2.根绝拦截方法的返回结果进行处理

如果进行了拦截,则会调用到super.dispatchTouchEvent(event),最终会调用到View类的dispatchTouchEvent(event)

如果没有进行拦截,则会对自己内部的所有子View进行判断,是否有焦点,是否在事件坐标范围之内等等一系列,然后调用该View的dispatchTouchEvent(event)(这里补充一下,这个子View可以是ViewGroup类型的也可以是View类型的。所以如果是viewGroup类型的还会把这个流程走一遍,直到找到我们需要的View)

还需要注意的是事件传递在viewgroup这个过程才有拦截事件的方法!

5. View

View类型的分发方法和ViewGroup的作用不一样,主要是确定怎么消费事件

判断mOnTouchListener.onTouch(this, event)的返回值,如果返回true,后边onTouchEvent(event)就不会响应了,如果返回false,则会调用自身onTouchEvent(event)消费事件,如果onTouchEvent返回false,则回到上以及viewgroup的onTouchEvent进行处理,以此类推,直到最后事件被消费。