1、input事件对应的trace
安卓中一个事件的主要流向要经过几个队列,从系统捕捉分发、准备发给应用 、已发送,再到应用处理
• iq(inboundqueue):⽤来标识inputDispatcher收到的InputReader发送的事件
• oq(outboundqueue):队列中即将发给应用的的事件
• wq(wait queue):已经发给应用,等待应用处理反馈后移除的事件
• ap:pending(App pending input )应用需要处理的事件
下面这张图是一个概览图,以滑动桌面为例 (滑动桌面包括一个 Input_Down 事件 + 若干个 Input_Move 事件 + 一个 Input_Up 事件,这些事件和事件流都会在 Systrace 上有所体现,这也是我们分析 Systrace 的一个重要的切入点),主要牵扯到的模块是 SystemServer 和 App 模块,其中用蓝色标识的是事件的流动信息,红色的是辅助信息。
InputReader 和 InputDispatcher 是跑在 SystemServer 里面的两个 Native 线程,负责读取和分发 Input 事件,我们分析 Systrace 的 Input 事件流,首先是找到这里。下面针对上图中标号进行简单说明
- InputReader 负责从 EventHub 里面把 Input 事件读取出来,然后交给 InputDispatcher 进行事件分发
- InputDispatcher 在拿到 InputReader 获取的事件之后,对事件进行包装和分发 (也就是发给对应的)
- OutboundQueue 里面放的是即将要被派发给对应 AppConnection 的事件
- WaitQueue 里面记录的是已经派发给 AppConnection 但是 App 还在处理没有返回处理成功的事件
- PendingInputEventQueue 里面记录的是 App 需要处理的 Input 事件,这里可以看到已经到了应用进程
- deliverInputEvent 标识 App UI Thread 被 Input 事件唤醒
- InputResponse 标识 Input 事件区域,这里可以看到一个 Input_Down 事件 + 若干个 Input_Move 事件 + 一个 Input_Up 事件的处理阶段都被算到了这里
- App 响应 Input 事件 : 这里是滑动然后松手,也就是我们熟悉的桌面滑动的操作,桌面随着手指的滑动更新画面,松手后触发 Fling 继续滑动,从 Systrace 就可以看到整个事件的流程
2、事件响应流程
2.1、触控事件的读取
2.2、分发触控事件
flush:遍历事件queue,将事件进⾏分发
notifyMotion:处理home 按键、声⾳键、锁屏键等。将触控事件放⼊iq队列。唤起线程,进⾏
进⾏⼀次分发。
dispatchOnceInnerLocked :找到对应窗⼝,将事件分给对应窗⼝
2.3、寻找窗口
2.4、触控事件发送到目标窗口
prepareDispatchCycled:获取⽬标窗⼝的连接
prepareDispatchCycleLocked:会检测⼀下链接的状态,将事件放⼊准备给⽬标窗⼝的发送的事
件队列。
startDispatchCycleLocked:分发事件,发送后将outBundleQueue 队列中移除该事件。
publishMotionEvent:构建InputMessage,调⽤成员变量InputChannel的sendMessage⽅法
发送input事件,
2.5、App端监听
setView:创建inputChanel,通过bind调⽤传给WMS,创建WindowInputEventReceiver对象,并
将inputChannel 和主线程looper传⼊。
nativeInit:将java层的inputChannel 和messageQueue转成native 层对应的inputChannel 和
messageQueue
setFdEvents:将inputChannel 中client 端socket的fd 传⼊looper,收到事件会回调handleEvent
consumeEvents 处理 输⼊事件,回调java 层的dispatchInputEvent,然后回调onInputEvent
2.6、UI线程对触控事件的分发处理
enqueueInputEvent: 将事件放⼊ aq:pending 队列
doProcessInputEvents:从aq:pending 队列中头节点进⾏分发
deliverInputEvent:处理⼀些按键、输⼊法事件,匹配相应的InputState,并调⽤InputStage的deliver⽅法
deliver:处理⼀些flag,以及判断事件是否该被抛弃
onProcess:将按键事件和触摸事件分开处理,调⽤processPointEvent 处理view 的触摸事件
processPointEvent:调⽤DecorView 的 dispatchPointerEvent,dispatchPointerEvent调⽤dispatchTouchEvent