Input概述

Post on Feb 10, 2023 by Wei Lin

Input系统

Android Input(一)-相关模块初始化

Input事件

在Android应用程序中,有一类特殊的消息,是专门负责与用户进行交互的,它们就是触摸屏和键盘等输入事件即Input事件,用户的点击、滑动、长按等操作,都属于input事件。

触摸屏和键盘事件是统一由系统输入管理器InputManager进行分发的。也就是说,InputManager负责从硬件接收输入事件,然后再将接收到的输入事件分发到当前激活的窗口进行处理。此外,InputManager也能接收模拟的输入事件,用来模拟用户触摸和点击等事件。

当前激活的窗口所运行在的线程接收到InputManager分发过来的输入事件之后,会将它们封装成输入消息,然后交给当前获得焦点的控件处理。

Input相关模块

(1) 硬件底层及内核

在硬件层,物理输入设备会生成描述状态更改(例如按键按压和轻触接触点)的信号,设备固件以某种方式编码和传输这些信号。


(2) 驱动及内核

然后信号由 Linux内核(Linux内核为许多标准的外围设备提供驱动程序)中的设备驱动程序解码。设备驱动程序负责通过 Linux 输入协议将设备特定信号转换为标准输入事件格式。


(3) EventHub组件

Android EventHub 组件通过打开与每个输入设备关联的 驱动程序从内核读取输入事件。其作用是将来源不同的各种信息,转化成为一种类型的信息,然后将这些信息提交到上层。

EventHub可以看成是输入消息的集散地,因为android支持多种输入设备,而各种设备的消息类型可能不一样,为了统一管理这些输入消息,Android提出了EventHub的概念,所有的输入事件都会通过EventHub收集,并通过EventHub传递给InputReader,这样对上层来说,就不需要关注底层设备的多样性,减少了上层使用的复杂性。EventHub同时还负责扫描和加载所有的输入设备,InputReader在第一次读取数据的时候会扫描所有的输入设备,并保存每个设备的配置信息。


(4) InputReader

Android InputReader 组件根据设备类别解码输入事件,转换成事件(Event)后传给Input Dispatcher。


(5) InputDispatcher

将InputReader传送过来的Events分发给合适的窗口,并监控ANR。


(6) InputManagerService

负责InputReader 和 InputDispatcher的创建,并提供Policy 用于Events的预处理。


(7) WindowManagerService

管理InputManager 与 View(Window) 以及 ActivityManager 之间的通信。


(8) View and Activity

接收按键并处理。

Input概述1.png

Input事件处理过程

Linux 输入协议在 linux/input.h 内核头文件中定义了一组标准事件类型和代码,输入设备驱动程序负责通过 Linux 输入协议将设备特定信号转换为标准输入事件格式,

接下来,Android EventHub组件通过打开与每个输入设备关联的 evdev 驱动程序从内核读取输入事件,

然后,Android InputReader 组件根据设备类别解码输入事件,并生成 Android 输入事件流,在此过程中,Linux 输入协议事件代码将根据输入设备配置、键盘布局文件和各种映射表,转化为 Android 事件代码。


大致处理过程如下:

  • 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 事件的处理阶段都被算到了这里;
  • App 响应处理Input 事件,内部会在其界面View树中传递处理。

流程图

Input概述2.png