Android FrameWork Input触控事件处理流程 笔记

一 Input 事件概念

input 是最常见的事件之一,用户的点击、滑动、长按等操作,都属于 input 事件驱动。Android系统是基于事件驱动, input 属于其中的一种。input 的核心就是 InputReader 和 InputDispatcher。

二Input 事件 流程分析

从桌面点击应用图标启动应用来开始看整个 Input 事件流程。

  1. system_server的native线程InputReader首先负责从EventHub中利用linux的epolle机制监听并从屏幕驱动读取上报的触控事件,然后唤醒另外一条native线程InputDispatcher负责进行进一步事件分发(对事件进行包装后)。
  2. InputDispatcher中会先将事件放到InboundQueue也就是“iq”队列中,然后寻找具体处理input事件的目标应用窗口,并将事件放入对应的目标窗口OutboundQueue也就是“oq”队列中等待通过SocketPair双工信道发送到应用目标窗口中。(这里是通过socket通信 不是binder )
  3. 当事件发送给具体的应用目标窗口后,会将事件移动到WaitQueue也就是“wq”中等待目标应用处理事件完成,并开启倒计时,如果目标应用窗口在5S内没有处理完成此次触控事件,就会向system_server报应用ANR异常事件。
  4. 当input触控事件传递到桌面应用进程后(桌面应用也是个app 只不过是系统级别的),Input事件到来后先通过enqueueInputEvent函数放入“aq”本地待处理队列中,并唤醒应用的UI线程在deliverInputEvent的流程中进行input事件的具体分发与处理。
  5. 具体会先交给在应用界面Window创建时的ViewRootImpl#setView流程中创建的多个不同类型的InputStage中依次进行处理(比如对输入法处理逻辑的封装ImeInputStage),整个处理流程是按照责任链的设计模式进行(跟okHttp 一样 )。
  6. 最后会交给ViewPostImeInputStage中具体进行处理,这里面会从View布局树的根节点DecorView开始遍历整个View树上的每一个子View或ViewGroup界面进行事件的分发、拦截、处理的逻辑(这里客户端开发同学可以进行拦截处理le)。
  7. 最后触控事件处理完成后会调用finishInputEvent结束应用对触控事件处理逻辑,这里面会通过JNI调用到native层InputConsumer的sendFinishedSignal函数通知InputDispatcher事件处理完成,从触发从"wq"队列中及时移除待处理事件以免报ANR异常。

重要类解释
InputReader负责从EventHub里面把Input事件读取出来,然后交给 InputDispatcher 进行事件分发

InputDispatcher在拿到 InputReader获取的事件之后,对事件进行包装后,寻找并分发到目标窗口

InboundQueue队列(“iq”)中放着InputDispatcher从InputReader中拿到的input事件

OutboundQueue(“oq”)队列里面放的是即将要被派发给各个目标窗口App的事件

WaitQueue队列里面记录的是已经派发给 App(“wq”),但是 App还在处理没有返回处理成功的事件

PendingInputEventQueue队列(“aq”)中记录的是应用需要处理的Input事件,这里可以看到input事件已经传递到了应用进程

deliverInputEvent 标识 App UI Thread 被 Input 事件唤醒

InputResponse 标识 Input 事件区域,这里可以看到一个 Input_Down 事件 + 若干个 Input_Move 事件 + 一个 Input_Up 事件的处理阶段都被算到了这里

你可能感兴趣的:(Android,framework,android)