android 输入系统

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

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; 事件值

}

frameworks/native/services/inputflinger/reader/include/EventHub.h

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

InputReader(事件快递员) :

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

InputDispatcher(事件分拣员) :

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

InputManager(调度中心) :

    • 管理InputReader和InputDispatcher,创建并启动它们的工作线程。

  1. 按键事件类型

RawEvent的 type ==EV_KEY:

rawEvent 的code 对应android的scanCode,

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

frameworks/base/data/keyboards/Generic.kl

  1. 触摸事件类型

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 等)。
  • 用途:实现压感功能,例如绘图应用中根据压力调整笔触粗细。

3.EV_SYN(同步事件)​​

  • ​​核心作用​​:标记事件数据包的边界,确保用户空间程序能完整处理一组事件

·  ​​子类型​​:

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

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

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

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

4.EV_REL(相对坐标事件)​​

  • ​​功能​​:报告相对位移变化,适用于鼠标等设备

5.EV_SW(开关事件)​​

  • ​​功能​​:报告二进制状态切换,如设备休眠/唤醒、盖子开合等

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 → 应用窗口

InputReader → InputDispatcher

    1. 通过QueuedInputListener将封装好的事件传递给InputDispatcher,存入mInboundQueue队列。

InputDispatcher 派发事件

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/82711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu中,c和c+程序,预编译、编译、链接和运行命令

目录 安装编译器一.c编译运行(粗暴简单)1.编写 C 程序:2. 预处理:3.编译:4. 汇编:5. 链接:6.运行 二.c编译运行(粗暴简单)1.编写 C 程序:2.预处理&#xff1a…

【FastAPI】--2.进阶教程(一)

【FastAPI】--基础教程-CSDN博客 app.get和post的参数: 参数类型说明pathstr路由路径(如 "/marks"),必填。response_modelType[T]定义响应数据的模型(如 percent),会自动校验和序列…

KT6368A通过蓝牙芯片获取手机时间详细说明,对应串口指令举例

一、功能简介 KT6368A双模蓝牙芯片支持连接手机,获取手机的日期、时间信息,可以同步RTC时钟 1、无需安装任何app,直接使用系统蓝牙即可实现 2、同时它不影响音频蓝牙,还支持一些简单的AT指令进行操作 3、实现的方式&#xff1…

【平面波导外腔激光器专题系列】用于光纤传感的低噪声PLC外腔窄线宽激光器

----翻译自Mazin Alalusi等人的文章 摘要 高性价比的 1550 nm DWDM平面外腔 &#xff08;PLANEX&#xff09; 激光器是干涉测量、布里渊、LIDAR 和其他光传感应用的最佳选择。其线宽<3kHz、低相位/频率噪声和极低的RIN。 简介 高性能光纤分布式传感技术是在过去几年中开发…

企业微信内部网页开发流程笔记

背景 基于ai实现企微侧边栏和工作台快速问答小助&#xff0c;需要h5开发&#xff0c;因为流程不清楚摸索半天&#xff0c;所以记录一下 一、网页授权登录 1. 配置步骤 1.1 设置可信域名 登录企业微信管理后台 进入"应用管理" > 选择开发的具体应用 > “网…

WORD 转 PDF 工具:排版 / 图片 / 表格批量转换提升办公效率

各位办公小能手们&#xff0c;今天来聊聊文档工具里的WORD转PDF工具&#xff01;这玩意儿到底是干啥的呢&#xff1f;咱来好好说道说道。 先说核心功能。第一个就是格式转换&#xff0c;能把Word文档转换成PDF&#xff0c;不管是格式、排版&#xff0c;还是图片、表格啥的&…

从逆流监测到智慧用电:ADL200N-CT系列单相导轨表赋能家庭绿色能源

在新能源浪潮席卷全球的当下&#xff0c;阳台光伏以及家庭储能&#xff08;户储&#xff09;系统逐渐成为众多追求绿色生活、渴望实现能源自主家庭的新选择。它不仅能有效利用太阳能等清洁能源&#xff0c;还能在用电高峰时段为家庭提供稳定电力支持&#xff0c;降低用电成本。…

std::thread的说明与示例

源于通义千问 在 C 中&#xff0c;std::thread 支持传递多种类型的函数作为线程入口点。你可以传递普通函数、类的成员函数、Lambda 表达式、函数对象&#xff08;仿函数&#xff09;等。以下是详细的说明和示例。 1. 传递普通函数 普通函数是最简单的用法。 示例 #include…

【Day38】

DAY 38 Dataset和Dataloader类 对应5. 27作业 知识点回顾&#xff1a; Dataset类的__getitem__和__len__方法&#xff08;本质是python的特殊方法&#xff09;Dataloader类minist手写数据集的了解 作业&#xff1a;了解下cifar数据集&#xff0c;尝试获取其中一张图片 import …

RabbitMQ 集群与高可用方案设计(三)

五、高可用方案设计与实现 &#xff08;一&#xff09;负载均衡与代理 1. HAProxy 配置 HAProxy 是一款广泛应用的开源负载均衡器和代理服务器&#xff0c;它能够实现对 RabbitMQ 集群节点的负载均衡和健康检查&#xff0c;有效提高系统的可用性和性能。以下是使用 HAProxy …

机器学习第二十四讲:scikit-learn → 机器学习界的瑞士军刀

机器学习第二十四讲&#xff1a;scikit-learn → 机器学习界的瑞士军刀 资料取自《零基础学机器学习》。 查看总目录&#xff1a;学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章&#xff1a;DeepSeek R1本地与线上满血版部署&#xff1a;超详细手把手指南 Scikit-…

百度ocr的简单封装

百度ocr地址 以下代码为对百度ocr的简单封装,实际使用时推荐使用baidu-aip 百度通用ocr import base64 from enum import Enum, unique import requests import logging as logunique class OcrType(Enum):# 标准版STANDARD_BASIC "https://aip.baidubce.com/rest/2.0…

Ubuntu20.04 gr-gsm完整安装教程

gr-gsm完整安装教程 安装gnuradio3.8安装依赖项指定gnuradio源安装gnuradio 安装gr-gsm安装依赖项安装gr-gsm修改环境变量 安装成功 安装gnuradio3.8 安装依赖项 sudo apt install git cmake g libboost-all-dev libgmp-dev swig python3-numpy python3-mako python3-sphinx …

(自用)Java学习-5.15(模糊搜索,收藏,购物车)

1. 模糊搜索商品功能 前端实现&#xff1a; 通过解析URL参数&#xff08;如search联想&#xff09;获取搜索关键字&#xff0c;发送AJAX GET请求到后端接口/product/searchGoodsMessage。 动态渲染搜索结果&#xff1a;若结果非空&#xff0c;循环遍历返回的商品数据&#xff…

STM32 TIM 定时器深度剖析:结构、时基、中断与应用开发(超形象详解)

文章目录 定时器&#xff08;TIM&#xff09;定时器种类与分布定时器的基本结构时基单元时基单元基本结构计数器计数方向时基单元时钟来源计算寄存器预加载机制 自制延时函数获取单片机当前时间实现延迟函数初始化定时器3的时基单元配置中断编写中断响应函数测试延迟函数 定时器…

Java使用minio上传整个目录下的所有内容

目录 1、添加相关配置 2、添加依赖 3、实现方法 1️⃣基础版&#xff1a; 2️⃣优化版&#xff08;推荐使用&#xff09;&#xff1a; 3️⃣上传远程主机上的目录内容&#xff1a; 4️⃣直接上传远程主机中的目录内容 业务背景&#xff1a;需要需要minio进行上传指定目录下所有…

Python的分布式网络爬虫系统实现

1. 系统架构概述 一个典型的分布式网络爬虫系统通常包含以下几个核心组件&#xff1a; 1.主节点&#xff08;Master Node&#xff09;&#xff1a; 任务调度&#xff1a;负责将抓取任务分配给各个工作节点。URL 管理&#xff1a;维护待抓取的 URL 队列和已抓取的 URL 集合&a…

AI工具的选择:Dify还是传统工具?

从纯技术视角出发&#xff0c;选择Dify还是传统开发工具需要基于六个核心维度进行理性决策。以下为结构化分析框架&#xff0c;附典型场景示例&#xff1a; 1. 开发效率 vs 控制力权衡矩阵 维度Dify优势场景传统工具优势场景迭代速度需求明确的标准CRUD&#xff08;如后台管理…

2.3 TypeScript 非空断言操作符(后缀 !)详解

在 TypeScript 中&#xff0c;当你开启了严格的空值检查&#xff08;strictNullChecks&#xff09;后&#xff0c;变量如果可能是 null 或 undefined&#xff0c;就必须在使用前进行显式的判断。为了在某些场景下简化代码&#xff0c;TypeScript 提供了非空断言操作符&#xff…

深度学习:损失函数与激活函数全解析

目录 深度学习中常见的损失函数和激活函数详解引言一、损失函数详解1.1 损失函数的作用与分类1.2 回归任务损失函数1.2.1 均方误差&#xff08;MSE&#xff09;1.2.2 平均绝对误差&#xff08;MAE&#xff09; 1.3 分类任务损失函数1.3.1 交叉熵损失&#xff08;Cross-Entropy&…