美文网首页
Android事件分发原理

Android事件分发原理

作者: 三十五岁养老 | 来源:发表于2022-03-12 20:27 被阅读0次

    在Android中,Touch事件的分发分服务端和应用端。

    服务端

    服务端由WindowManagerService(借助InputManagerService)负责采集和分发的,在应用端则是由ViewRootImpl(内部有一个mView变量指向View树的根,负责控制View树的UI绘制和事件消息的分发)负责分发的。

    image.png

    当输入设备可用时,比如触屏,Linux内核会在/dev/input中创建对应的设备节点。
    IMS(InputManagerService)监听/dev/input下的所有的设备节点,当设备节点有数据时会将数据进行加工处理并找到合适的Window(WMS寻找),将输入事件派发给他

    • 事件信号是物理文件存储数据,位置:dev/input
    • linux 有提供相关的文件监控api:inotify 、 epoll( ①inotify能监控文件变化产生FD ②epoll可以监控FD,以此配合完成文件的监控与监听)
    • android 定义了两个线程来处理dev/input下面的信号
    • 专门写了一个EventHub对象,里面用inotify+epoll对dev/input下进行监控!
    • 将该对象放到InputReaderThread当中去执行,轮训getEvent(),这个里面有epoll_wait,相当于wait-notify机制,唤醒的触发点是/dev/input下的文件被改变,这个文件由驱动去推送数据
    • InputReaderThread当中将/dev/input下的数据提取,封装,然后交给InputDispathcerThread
    • InputDispathcerThread给最终选择到对应的ViewRootImpl(Window)
    • 中间的通信机制通过socketpair进行,两边一人一组socketpair然后在ViewRootImpl中对于Channel的连接的文件进行监控,最终上层接受到touch信号。

    client端

    事件分发.PNG
    • 每一个Activity内部都包含一个Window用来管理要显示的视图。而Window是一个抽象类,其具体实现是 PhoneWindow类。
    • DecovrView作为PhoneWindow的一个内部类,实际管理着具体视图的显示。他是FrameLayout的子类,盛放着我们的标题栏和根视图。我们自己写的一些列View和ViewGroup都是由他来管理的。
    • 事件自顶向下的传递过程应该是这样的:
      Activity(不处理)-> 根View -> 一层一层ViewGroup(如果有的话) -> 子View
    • 如果传递到最后我们的子View们没有处理这一事件怎么办呢?这时候就会原路返回,最终传递给Activity。只有当Activity也没有处理这一事件时,这一事件才会被丢弃。
      Activity(不处理则丢弃) <- 根View <- 一层一层ViewGroup(如果有的话) <- 子View

    具体在传递事件的时候,是由以下三个方法来控制的:

    dispatchTouchEvent : 分发事件
    onInterceptTouchEvent : 拦截事件
    onTouchEvent : 消费事件
    这三个方法有一个共同点,就是他们具体是否执行了自己的功能(分发、拦截、消费)完全由自己的返回值来确定,返回true就表示自己完成了自己的功能(分发、拦截、消费)。不同之处除了功能外,还有使用的场景。dispatchTouchEvent()和onTouchEvent()这两个方法,无论是Activity ViewGroup 还是View,都会被用到。而onInterceptTouchEvent()方法因为只是为了拦截事件,那么Activity和View一个在最顶层,一个在最底层,也就没必要使用了。因此在View 和 Activity中是没有onInterceptTouchEvent()方法的。

    参考链接:https://blog.csdn.net/qq_42165012/article/details/123163462

    相关文章

      网友评论

          本文标题:Android事件分发原理

          本文链接:https://www.haomeiwen.com/subject/mkjqdrtx.html