Android输入系统梳理

本文详细介绍了Android输入系统的流程,从Linux内核如何处理输入设备的中断,到InputManagerService如何封装和分发事件,再到InputDispatcher如何找到合适的目标窗口。重点讨论了InputReader和InputDispatcher的角色,以及ViewRootImpl在处理输入事件中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android输入系统梳理

输入系统总体流程与参与角色

在这里插入图片描述
Android最常见的输入设备是触摸屏,然而除了触摸屏,安卓还支持其他输入设备如鼠标、游戏手柄、键盘等。当输入设备可用时,Linux内核会在/dev/input/下创建对应的名为event0~n或其他名称的设备节点。而当输入设备不可用时,则会将对应的节点删除。在用户空间可以通过ioctl的方式从这些设备节点中获取其对应的输入设备的类型、厂商、描述等信息。
当用户操作输入设备时,Linux内核接收到相应的硬件中断,然后将中断加工成原始的输入事件数据并写入其对应的设备节点中,在用户空间可以通过read()函数将事件数据读出。Android输入系统的工作原理概括来说,就是监控/dev/input/下的所有设备节点,当某个节点有数据可读时,将数据读出并进行一系列的翻译加工,然后在所有的窗口中寻找合适的事件接收者,并派发给它。
流程图中设备节点负责承载输出原始输入数据,InputManagerService负责封装加工原始输入数据为KeyEvent、MotionEvent等输入事件,然后通过InputDispatcher分发给WMS管理的Window,最在在APP内部从ViewRootImpl开始,开始输入事件在视图View系统中的消费处理。

设备节点上报数据

linux内核写入到设备节点的数据格式和例子如下,数据都是16进制的

格式 时间戳 设备节点路径 事件类型 事件代码 事件的值
举例:按下电源键 1262.443489 /dev.input.event0 0001 0074 00000001

代码对应结构为RawEvent
在这里插入图片描述

通过adb shell getevent命令可以直接获取某个节点的上报数据
通过adb shell sendevent命令可以模拟linux内核给设备节点写入数据,比如可以模拟点击电源键,然后手机就会有亮屏灭屏等行为,这个给自动化测试中提供了一个切入手段

InputManagerService

在这里插入图片描述
在这里插入图片描述

  • InputManagerService,一个Android系统服务,它分为Java层和Native层两部分。Java层负责与WMS通信。而Native层则是InputReader和InputDispatcher两个输入系统关键组件的运行容器。
  • EventHub,直接访问所有的设备节点。并且正如其名字所描述的,它通过一个名为getEvents()的函数将所有输入系统相关的待处理的底层事件返回给使用者。这些事件包括原始输入事件、设备节点的增删等。
  • InputReader,是IMS中的关键组件之一。它运行于一个独立的线程中,负责管理输入设备的列表与配置,以及进行输入事件的加工处理。它通过其线程循环不断地通过getEvents()函数从EventHub中将事件取出并进行处理。对于设备节点的增删事件,它会更新输入设备列表与配置。对于原始输入事件,InputReader对其进行翻译、组装、封装为包含更多信息、更具可读性的输入事件,然后交给InputDispatcher进行派发。
  • InputReaderPolicy,它为InputReader的事件加工处理提供一些策略配置,例如键盘布局信息等。
  • InputDispatcher,是IMS中的另一个关键组件。它也运行于一个独立的线程中。InputDispatcher中保管了来自WMS的所有窗口的信息,其收到来自InputReader的输入事件后,会在其保管的窗口中寻找合适的窗口,并将事件派发给此窗口。
  • InputDispatcherPolicy,它为InputDispatcher的派发过程提供策略控制。例如截取某些特定的输入事件用作特殊用途,或者阻止将某些事件派发给目标窗口。一个典型的例子就是HOME键被InputDispatcherPolicy截取到PhoneWindowManager中进行处理,并阻止窗口收到HOME键按下的事件。
  • WMS,虽说不是输入系统中的一员,但是它却对InputDispatcher的正常工作起到了至关重要的作用。当新建窗口时,WMS为新窗口和IMS创建了事件传递所用的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值