尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

android 输入系统

android 输入系统
📅 发布时间:2026/7/16 19:41:41

一、输入系统的核心角色与分层架构

Android 输入系统的本质是桥梁:一端连接硬件驱动产生的原始事件,另一端将事件精准派发给应用窗口。整个过程涉及三层架构和多个关键组件,可类比为 “快递分拣系统”:

1. 硬件与内核层(源头)

  • 角色:当用户触摸屏幕或按下按键时,硬件驱动将事件写入设备节点(如/dev/input),生成原始的内核事件(类似 “快递包裹的原始数据”)。
  • 技术实现:通过EventHub(事件枢纽)监听设备路径,使用epoll和inotify机制高效检测事件变化和设备插拔。

驱动上报

struct RawEvent{

nsecs_t when;

nsecs_t readtime;

int32_t deviceId; 输入设备唯一标识符

int32_t type; 事件类型 如EV_KEY, EV_ABS

int32_t code; 事件码

int32_t value; 事件值

}

RawEvent的定义位于 frameworks/native/services/inputflinger/reader/include/EventHub.h

2. Native 层(事件处理与分发)

InputReader(事件快递员):

    • 从EventHub读取原始事件(如触摸坐标、按键码),按规则封装为标准事件(如MotionEvent、KeyEvent)。
    • 类比:将 “原始包裹数据” 解析为 “标准化快递单”。

InputDispatcher(事件分拣员):

    • 接收InputReader处理后的事件,结合窗口信息(如焦点窗口),将事件派发给对应的应用窗口。
    • 类比:根据 “快递单地址” 将包裹分拣到正确的配送路线。

InputManager(调度中心):

    • 管理InputReader和InputDispatcher,创建并启动它们的工作线程。
2.1 按键事件类型

RawEvent的 type == EV_KEY:

rawEvent 的code 对应android的scanCode,

scanCode 通过 Generic.kl 映射到android 的keycode。

通常使用 frameworks/base/data/keyboards/Generic.kl 建立linux到android的按键映射关系。

2.2 触摸事件类型

RawEvent的type ==EV_ABS (绝对坐标事件)

在 Linux 输入子系统(Input Subsystem)中,多点触控(Multi-Touch)事件通过一系列以 ABS_MT_ 开头的绝对坐标类事件代码(ABS 代表 Absolute Position)来描述每个触摸点(Slot)的属性。以下是你列出的各个 ABS_MT_ 事件的详细说明:

1. ABS_MT_SLOT
  • 作用:标识当前操作的触摸点槽位(Slot)。
    多点触控设备通过 “槽位” 机制管理多个触摸点(类似数组索引),每个槽位对应一个独立的触摸点。当设备报告某个触摸点的属性时,需先通过 ABS_MT_SLOT 指明操作的是哪个槽位。
  • 值范围:通常从 0 开始递增(如 0、1、2...),具体取决于设备支持的最大触摸点数(如 5 点触控则槽位为 0~4)。
2. ABS_MT_TRACKING_ID
  • 作用:为每个触摸点分配唯一的追踪 ID,用于在触摸点生命周期内(按下、移动、抬起)标识其身份。
    • 当触摸点按下时,系统分配一个非负整数 ID(如 1、2...);
    • 当触摸点抬起时,ID 会被重置为 -1(表示该槽位不再被占用)。
  • 值范围:
    • 有效触摸点:>= 0(如 1, 2);
    • 无效 / 释放的槽位:-1。
  • 用途:区分不同触摸点(即使槽位重用),例如:
    • 槽位 0 先用于触摸点 A(ID=1),抬起后 ID 重置为 -1;
    • 新触摸点 B 按下时,可能再次使用槽位 0,但分配新 ID=2。
      通过 ID 可确保触摸点的移动轨迹不会因槽位重用而混淆。
3. ABS_MT_TOUCH_MAJOR
  • 作用:表示触摸点接触面积的主轴长度(椭圆的长轴,单位为像素或设备特定单位)。
    可粗略理解为触摸点的 “宽度” 或 “接触区域大小”,例如手指按下时的接触面积。
  • 值范围:通常为正整数,值越大表示接触面积越大。
  • 示例:手指轻轻触摸时值为 20,用力按下时值为 30
4. ABS_MT_WIDTH_MAJOR
  • 作用:表示触摸点接触面积的次轴长度(椭圆的长轴,单位与 ABS_MT_TOUCH_MAJOR 一致)。
    在某些设备中,TOUCH_MAJOR 和 WIDTH_MAJOR 可能分别对应椭圆的长轴和短轴,用于描述触摸点的形状。
  • 值范围:正整数,通常与 ABS_MT_TOUCH_MAJOR 成比例。
5. ABS_MT_POSITION_X 和 ABS_MT_POSITION_Y
  • 作用:
    • ABS_MT_POSITION_X:触摸点在屏幕坐标系中的 X 轴坐标(水平位置)。
    • ABS_MT_POSITION_Y:触摸点在屏幕坐标系中的 Y 轴坐标(垂直位置)。
  • 坐标原点:通常为屏幕左上角(X=0, Y=0),向右 / 向下递增。
  • 单位:设备特定的逻辑单位(如像素、毫米等),需通过输入子系统校准后映射到屏幕像素。
6. ABS_MT_PRESSURE
  • 作用:表示触摸点的压力值,用于检测触摸力度(如手指按下的轻重)。
    • 值为 0 时表示无压力(触摸点抬起);
    • 值越大表示压力越大。
  • 值范围:通常为 0 到设备支持的最大值(如 255、1024 等)。
  • 用途:实现压感功能,例如绘图应用中根据压力调整笔触粗细。
2.3.EV_SYN(同步事件)​​
  • ​​核心作用​​:标记事件数据包的边界,确保用户空间程序能完整处理一组事件

· ​​子类型​​:

  • ​​SYN_REPORT​​:表示当前数据包结束,触发用户空间处理累积事件(如鼠标移动后必须发送该事件完成坐标更新)

· ​​SYN_DROPPED​​:内核缓冲区溢出时通知用户丢弃数据包并重新查询设备状态

· ​​SYN_MT_REPORT​​:多点触控协议中分隔不同触点的数据包(Type A协议使用)

· ​​底层依赖​​:驱动必须正确发送该事件,否则用户空间无法识别事件边界

2.4.EV_REL(相对坐标事件)​​
  • ​​功能​​:报告相对位移变化,适用于鼠标等设备
2.5.EV_SW(开关事件)​​
  • ​​功能​​:报告二进制状态切换,如设备休眠/唤醒、盖子开合等
2.6.EV_MSC(杂项事件)​​
  • ​​功能​​:处理无法归类到其他类型的事件,如硬件特定状态或补充信息

3. Java 层(系统服务与交互)

InputManagerService(IMS,总控中心):

    • 作为 Android 系统服务(运行于system_server进程),通过 JNI 与 Native 层交互。
    • 与窗口管理服务(WMS)同步窗口信息,为InputDispatcher提供派发依据(如哪个窗口当前可见)。
    • 类比:“快递总控中心”,协调底层分拣与上层应用的对接。

二、启动流程详解:从 IMS 初始化到线程启动

IMS 的启动伴随system_server进程启动,整个过程可分为对象创建和线程启动两个阶段,涉及 Java 层、JNI 层和 Native 层的跨层调用。

1. 初始化阶段:搭建组件链路

/ /Java层:IMS初始化(InputManagerService.java)inputManager = new InputManagerService(context);

步骤 1:创建 Java 层 IMS 对象

初始化mHandler,运行在 “android.display” 线程(负责处理 Java 层消息)。

通过nativeInit调用 JNI,进入 Native 层初始化。

// JNI层:nativeInit(com_android_server_input_InputManagerService.cpp)NativeInputManager* im = new NativeInputManager(...);

步骤 2:创建 NativeInputManager(JNI 桥梁)

持有 Java 层 IMS 对象的引用(mServiceObj),作为 Native 层与 Java 层交互的桥梁。

创建EventHub(监听设备事件)和InputManager(管理读写线程)。

// Native层:InputManager构造(InputManager.cpp)

mDispatcher = new InputDispatcher(...); // 分拣员

mReader = new InputReader(...); // 快递员

步骤 3:创建 InputDispatcher 和 InputReader

  • InputDispatcher关联NativeInputManager(获取派发策略,如超时参数)。
  • InputReader通过QueuedInputListener与InputDispatcher建立连接(事件传递的枢纽)。

2. 启动阶段:激活工作线程

inputManager.start(); // 调用nativeStart

·启动 Native 层线程
通过InputManager.start()启动两个核心线程:

  • InputReaderThread:循环调用EventHub.getEvents()读取事件,交由InputReader处理。
  • InputDispatcherThread:循环处理事件队列,将事件派发给目标窗口。

·关键线程分工:

  • android.display 线程(Java 层):处理 IMS 的消息(如配置变更、ANR 通知)。
  • InputReaderThread(Native 层):专注读取硬件事件,不阻塞其他操作。
  • InputDispatcherThread(Native 层):专注事件派发,确保实时性。

三、事件如何从硬件传到应用?

事件分发链:InputReader → InputDispatcher → 应用窗口
  1. InputReader → InputDispatcher:
  2. 通过QueuedInputListener将封装好的事件传递给InputDispatcher,存入mInboundQueue队列。

InputDispatcher 派发事件:

  1. 从 WMS 获取焦点窗口信息(通过 IMS 同步),确定事件目标窗口。
  2. 通过InputChannel(跨进程通信通道)将事件发送给应用的InputConsumer,最终由ViewRootImpl处理并传递给界面组件(如按钮、文本框)。

四. 应用层的事件传递

ViewRootImpl ->DecorView 的dispatchTouchEvent

Android 系统ViewGroup的dispatchTouchEvent 是触摸事件分发核心方法,整个 Android 触摸分发、拦截、子 View 投递、滑动冲突全部由这段逻辑驱动。全程分为以下步骤:

1.安全校验与初始化:无障碍焦点、调试日志、安全过滤;
2.DOWN 事件重置状态:每次新手势按下清空上一轮触摸缓存;
3.判断是否拦截事件intercepted = onInterceptTouchEvent(ev):核心滑动判定入口(RecyclerView 左右 / 上下滑动判断就在这里);
4.未拦截时:遍历子 View,寻找能接收触摸的子 View,建立TouchTarget链表;
5.向所有有效子 TouchTarget 分发事件dispatchTransformedTouchEvent,拦截时给子 View 发送 CANCEL;
6.UP/CANCEL 手势结束,清空触摸状态;
7.返回handled标记当前 ViewGroup 是否消费本次触摸。

其中 dispatchTransformedTouchEvent 是ViewGroup 的私有方法。负责将触摸事件分发给子view。

三段触摸源码完整调用链路串联:

ViewGroup.dispatchTouchEvent(总调度:拦截判断、构建TouchTarget链表) ↓

dispatchTransformedTouchEvent(坐标转换、多指裁剪、下发CANCEL工具方法) ↓

View.dispatchTouchEvent(普通控件处理触摸:OnTouchListener > onTouchEvent)

手指按下 ACTION_DOWN
│
▼
Activity.dispatchTouchEvent()
│
▼
DecorView.dispatchTouchEvent()
│
▼
LinearLayout.dispatchTouchEvent()
│
├── LinearLayout.onInterceptTouchEvent()
│ │
│ ├── true → LinearLayout.onTouchEvent()
│ │
│ └── false → 继续向子 View 分发
▼
RecyclerView.dispatchTouchEvent()
│
├── RecyclerView.onInterceptTouchEvent()
│ │
│ ├── true → RecyclerView.onTouchEvent()
│ │
│ └── false → 继续分发给 ItemView
▼
ItemView.dispatchTouchEvent()
│
▼
Button.dispatchTouchEvent()
│
├── OnTouchListener.onTouch()
│ ├── true → 事件到此结束
│ └── false → 继续
│
▼
Button.onTouchEvent()
│
├── true → Button 消费事件
└── false → 事件逐层回传给父容器处理

相关新闻

  • 食品包装线实战:C#上位机+国产PLC落地自动化,这份避坑指南请收好
  • 网络攻击工具深度解析:Zarp框架架构与实战应用指南
  • 鸣潮游戏自动化工具ok-ww:解放双手的智能辅助解决方案

最新新闻

  • Claude 3.5推理能力实测:8大真实场景对比GPT-4o与Gemini 2.0,谁才是逻辑推理新标杆?
  • HsMod:基于BepInEx的炉石传说游戏体验增强技术方案解析
  • c++之多态篇
  • 浏览器真的能变成你的下一台电脑吗?探索OS.js的Web桌面革命
  • 华为ensp2024年11月期末考试-无套路-只为你过
  • Metabase企业级数据可视化架构深度解析与嵌入式分析实践

日新闻

  • Toon Boom Harmony 高效工作流:从节点视图到镜头标记的实战技巧
  • 真力时售后维修电话,为您提供专业腕表保养与故障修复服务权威公示(2026年7月最新) - 亨得利官方服务中心
  • 【C++】类和对象--构造函数进阶(初始化列表与explicit)

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号