总体流程:
在WindowManagerService启动过程中会启动InputManager的一个服务,在这个服务中会开启两个线程,一个读线程,负责从系统读取设备事件,并写入一个事件队列。一个分发线程,负责将事件分发到目标应用。
在Activity启动的过程中,会创建一个ViewRoot的实例,ViewRoot会初始化一个InputHandle的实例,并在setView 方法中,将其注册为消息接收通道的客户端 ,形成了一个服务端与客户端的通信管道,此时,服务端也会创建一块匿名共享内存来保存消息的具体信息。
当读线程接收到设备的事件后,分发线程会将事件的具体信息保存到匿名共享内存中,并通过通信管道通知客户端有事件发生。客户端得到通知后,会去共享内存中读取具体的事件信息。
客户端这边最先获取事件的是ViewRoot,ViewRoot通过InputHandle获取事件,然后将事件分发给DecorView,DecorView会现将事件给ContentView处理,如果ContentView没有处理,则会交给Activity处理。
在View这一层,事件先会分给ViewGroup,在ViewGroup中遍历后找到目标View之后交给目标View处理。
C++层
底层UML图如下:
InputManager:初始化的时候会初始化两个线程:InputDispatcherThread与InputReaderThread。并在start()函数里开启两个线程
EventHub:接收系统所有设备的事件,并提供了一个输入事件流
InputReaderThread:在loopThread中调用InputReader
InputReader通过调用EventHub的getEvent来读入输入事件,并把事件送到监听者。如有Motion事件的时候,事件会传递到InputListen的notifyMotion。
InputDispatcher:实现了InputListenerInterface,并分发事件给目标应用或窗口
InputListener:接收InputReader读入的事件,并将其放到一个事件队列中
InputPublisher:创建匿名内存与通信管道
InputChannel:通信通道,Java层InputChannel的本地类