Android Framework--事件分发

分发流程

 我们知道system_server会启动各种服务,其中包括InputManagerService,IMS的native层对应者一个NativeInputManager。事件分发的起源就在这里,NativeInputManager中有三个对象(EventHub,InputReader,InputDispatcher)各自都有一个工作线程。
 首先我们输入设备的设备驱动文件都在dev/input/event0~n这里,EventHub负责从驱动中取出输入事件,InputReader则负责将输入原始值转换成虚拟值,InputDispatcher则负责为输入事件寻找合适的窗口并分发下去。
 

此外这里还有两个点要说明
 第一个NativeInputManager有一个InputWindowHandle对象,它与WMS会有一个同步关系,保住IMS里可以知道当前所有的window
 第二个NativeInputManager与Window的通信并不是常见的Binder,而是SockerPair(详情自查),大致的工作原理就是这种通信方式有一对的InputChannel,window会持有一个InputChannel,IMS这边持有配对的InputChannel,这样只要找到合适的window就可以发过去了。

window这边的接收方是在ViewRootImpl的内部类WindowEventReceiver中进行处理,这边先说下事件消费的相关知识,一般的一个点击事件分DOWN,MOVE,UP几个阶段,DOWN阶段就会判断这个事件由谁来消费后续的MOVE,UP等都会分发到这个对象;事件由外向内层层分发。下面看下大致的分发流程:

  1. 先尝试分发给DecorView这边(可以理解为View视图体系这边),这时候可以用onKeyPreIme来拦截消费
  2. 之后尝试分发给输入法
  3. 最后还是分发给Decorview,这部分就是我们常见的(dispatchKeyevent之类的部分了)

最后详细说下第三部分,DecorView会先分发给Activity然后再由外而内层层分发下去,DOWN的阶段决定了谁消费这整个事件,所以只讨论DOWN阶段。

  • dispatchTouchEvent:返回true则表示本层要拦截消费这个事件
  • onInterceptTouchEvent:ViewGroup及其子类才有,返回true表示拦截这个事件,事件不会再往下层传递
  • 最后讨论下onTouchEvent和onTouch,其实它们是在View.dispatchTouchEvent里调用的,dispatchTouchEvent会先分发给OnTouchListener.onTouch,之后分发给onTouchEvent。

流程图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/xiaoru5127/article/details/76589480
今日推荐