当前位置: 首页 > news >正文

一文简单了解Android中的input流程

在 Android 中,输入事件(例如触摸、按键)从硬件传递到应用程序并最终由应用层消费。整个过程涉及多个系统层次,包括硬件层、Linux 内核、Native 层、Framework 层和应用层。我们将深入解析这一流程,并结合代码逐步了解输入事件的传递。
 Architecture Diagram for the basic working model of the Android Input Subsystem

1. 输入事件的产生与传递

输入事件的产生是从硬件触摸屏开始的。触摸屏等输入设备检测到用户的操作(如触摸、滑动),然后将这些事件传递给 Linux 内核。

  • 硬件层(触摸屏等):将物理触摸或按键操作转化为信号。
  • 内核层:Linux 内核中的 Input 子系统负责接收这些输入信号并生成相应的事件。

在 Android 系统中,输入事件从硬件传递到应用层的大致流程如下:

触摸屏(硬件层) → Linux 内核(Input子系统) → Native Input System(输入事件解析与分发)
→ Framework(事件管理) → 应用层(事件消费)

2. Linux 内核:输入事件的生成与处理

内核的 Input 子系统接收到输入事件后,将其转化为 input_event 结构。每个输入事件包括三部分:

  • type:事件的类型,例如 EV_ABS 表示绝对坐标事件。
  • code:事件的具体代码,例如 ABS_X 表示 X 轴坐标。
  • value:事件的值,例如坐标值。
代码示例

在 Linux 内核中,输入事件使用以下结构定义:

struct input_event {struct timeval time;  // 事件发生时间__u16 type;           // 事件类型__u16 code;           // 事件代码__s32 value;          // 事件值
};

当触摸屏收到用户的操作时,会产生一系列 input_event 事件,传递到 Linux Input 子系统。然后,内核会将这些事件通过 /dev/input/eventX 文件接口暴露给用户态。

3. Native 层:InputReader 和 InputDispatcher

Android 使用 InputReaderInputDispatcher 这两个关键组件来处理输入事件。

  • InputReader:从 Linux /dev/input/eventX 接口读取事件,并解析为 Android 系统可以理解的 MotionEvent 或 KeyEvent。
  • InputDispatcher:将 InputReader 解析后的事件分发给应用程序的 Window。
    在 Android 系统中,InputManagerService 是输入系统的核心服务,它在系统启动时被创建,并负责管理整个输入事件的读取和分发。
InputReader 代码流程

InputReader 中,EventHub 类负责打开 /dev/input/eventX 设备文件并读取事件。

void EventHub::openDevice(const char* deviceName) {// 打开设备文件int fd = open(deviceName, O_RDWR);// 将设备文件添加到输入设备列表中mDevices.push_back(fd);
}

InputReader::loopOnceInputReader 的核心处理函数,它不断从事件队列中读取事件并处理。

void InputReader::loopOnce() {// 读取事件processEvents();// 处理事件dispatchEvent();
}
InputDispatcher 代码流程

InputDispatcher 使用 dispatchEvent 方法将事件分发到合适的 WindowActivity

void InputDispatcher::dispatchEvent(const Event& event) {// 获取目标 Windowsp targetWindow = getTargetWindow(event);// 将事件发送给目标 WindowtargetWindow->sendEvent(event);
}

4. Framework 层:事件分发(WindowManagerService)

在 Framework 层,InputManagerService 将事件传递给 WindowManagerServiceWindowManagerService 负责管理所有窗口的输入焦点,并将事件转发给有焦点的窗口。

代码流程

WindowManagerService 中的 dispatchPointerEvent 方法会根据窗口焦点来分发事件。

public void dispatchPointerEvent(MotionEvent event) {// 获取焦点窗口WindowState focusedWindow = getFocusedWindow();if (focusedWindow != null) {// 将事件发送到焦点窗口focusedWindow.sendInputEvent(event);}
}

5. 应用层:事件消费(View 和 Activity)

最终,事件到达应用层。对于触摸事件,Android 使用 onTouchEvent 方法处理,而对于按键事件,则使用 onKeyDownonKeyUp 等方法处理。

示例代码

ActivityView 中,可以通过重写 onTouchEvent 来消费事件。

@Override
public boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 处理按下事件break;case MotionEvent.ACTION_MOVE:// 处理移动事件break;case MotionEvent.ACTION_UP:// 处理抬起事件break;}return super.onTouchEvent(event);
}

总结

  • 硬件层:产生输入事件并传递到内核。
  • Linux 内核:接收输入信号并转化为 input_event。
  • Native 层:InputReader 和 InputDispatcher 解析和分发事件。
  • Framework 层:WindowManagerService 负责将事件传递给对应的窗口。
  • 应用层:Activity 和 View 接收并消费事件。
    这一整套流程保证了从物理输入到应用响应的链路完整性和效率。

参考

Android Input Framework Architecture

相关文章:

一文简单了解Android中的input流程

在 Android 中,输入事件(例如触摸、按键)从硬件传递到应用程序并最终由应用层消费。整个过程涉及多个系统层次,包括硬件层、Linux 内核、Native 层、Framework 层和应用层。我们将深入解析这一流程,并结合代码逐步了解…...

【MySQL】SQL语言

【MySQL】SQL语言 文章目录 【MySQL】SQL语言前言一、SQL的通用语法二、SQL的分类三、SQLDDLDMLDQLDCL 总结 前言 本篇文章将讲到SQL语言,包括SQL的通用语法,SQL的分类,以及SQL语言的DDL,DML,DQL,DCL。 一、SQL的通用语法 在学习具体的SQL语句之前,先来…...

5.4.2-1 编写Java程序在HDFS上创建文件

本次实战涉及使用Java操作Hadoop HDFS,包括创建文件、判断文件存在性及异常处理。通过手动添加依赖、启动HDFS服务,成功在HDFS上创建和检查文件。进一步探索了文件操作的最佳实践,如检查文件存在性以避免重复创建,以及处理HDFS安全…...

The 3rd Universal CupStage 15: Chengdu, November 2-3, 2024(2024ICPC 成都)

Problem L. Recover Statistics 题目意思&#xff1a; 给定a, b, c三个值&#xff0c;确保构造的数列中包含满足题目的数量 解题思路&#xff1a; 100 中 选择a 50个&#xff0c; b45个&#xff0c; c4个。 #include <iostream>using namespace std;using ll long …...

显示微服务间feign调用的日志

第一步 package com.niuniu.common.config;import com.niuniu.common.CommonConstant; import com.niuniu.common.utils.UserContext; import feign.Logger; import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.context.annotation.…...

SOHO场景开局(小型,多子网):AP+管理型交换机+路由器+光猫

业务需求 1. 实现除光猫外&#xff0c;整网设备通过APP进行开局&#xff0c;开局部署完成后&#xff0c;能够通过APP远程运维。 2. 需要单独划分访客、办公、视频监控3个子网&#xff0c;其中访客子网供顾客无线上网使用&#xff0c;办公子网用于接入无线和有线办公终端&#x…...

Android - Pixel 6a 手机OS 由 Android 15 降级到 Android 14 操作记录

Pixel 6a 手机由 Android 14 升级到 Android 15了&#xff0c;但是由于一些原因又想降级回 Android 14&#xff0c; 能降吗&#xff1f;该怎么降级呢&#xff1f;本篇文章来记述实际操作过程&#xff0c;希望能给想做相同操作的人一些帮助。 答案当然是能降&#xff0c;而且我…...

linux系统kkFileView 配置https预览文件

思路&#xff1a; 1.kkfile的 context全局路径可以修改 context-path,比如&#xff1a;server.servlet.context-path 2.使用nginx反向代理 /kkfile 转发到 kkfile路径上 官网教程 ​​​​​​kkFileView - 在线文件预览 1、配置config/application.properties. server.se…...

stm32——通用定时器时钟知识点

&#xff08;该图来自小破站 铁头山羊老师的stm32标准库教学&#xff09;...

前端无感刷新token

摘要&#xff1a; Axios 无感知刷新令牌是一种在前端应用中实现自动刷新访问令牌&#xff08;access token&#xff09;的技术&#xff0c;确保用户在进行 API 请求时不会因为令牌过期而中断操作 目录概览 XMLHttpRequestAxiosFetch APIJQuni.request注意事项&#xff1a; 访问…...

针对股票评论的情感分类器

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月16日13点39分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文链接 点击开启你的论文编程之旅…...

Day18 Nim游戏

你和你的朋友&#xff0c;两个人一起玩 Nim 游戏&#xff1a; 桌子上有一堆石头。 你们轮流进行自己的回合&#xff0c; 你作为先手 。 每一回合&#xff0c;轮到的人拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。 假设你们每一步都是最优解。请编写一个函数&#xff…...

理解反射,学会反射:撬开私有性质(private)的属性与方法

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 个人主页&#xff1a;Gu Gu Study专栏&#xff1a;用Java学习数据结构系列喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹喜欢的话可以点个赞谢谢了。作者&#xff1a;小…...

Redis在高性能缓存中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 Redis在高性能缓存中的应用 Redis在高性能缓存中的应用 Redis在高性能缓存中的应用 引言 Redis 概述 定义与原理 发展历程 Redi…...

菲涅耳全息图

菲涅耳全息图&#xff1a;记录介质在物光波场的菲涅耳衍射区(物体到记录介质表面的距离在菲涅耳衍射区内)。 一、点源全息图的记录和再现 1.1 记录 设物光波和参考光波是从点源O(xo, yo, zo)和点源 R(xr, yr, zr)发出的球面波, 波长为λ1, 全息底片位于z0 的平面上, 与两个点源…...

STM32 BootLoader 刷新项目 (十) Flash擦除-命令0x56

STM32 BootLoader 刷新项目 (十) Flash擦除-命令0x56 1. STM32F407 BootLoader 中的 Flash 擦除功能详解 在嵌入式系统中&#xff0c;BootLoader 的设计是非常关键的部分&#xff0c;它负责引导主程序的启动、升级以及安全管理。而在 STM32F407 等 MCU 上实现 BootLoader&…...

POI word转pdf乱码问题处理

1.使用poi 转换word文档成pdf 导入依赖 <dependency><groupId>com.aspose</groupId><artifactId>words</artifactId><version>16.8.0</version></dependency>2.代码实现: SneakyThrowspublic void wordToPdf(String docPath,…...

【GeekBand】C++设计模式笔记11_Builder_构建器

1. “对象创建” 模式 通过 “对象创建” 模式绕开new&#xff0c;来避免对象创建&#xff08;new&#xff09;过程中所导致的紧耦合&#xff08;依赖具体类&#xff09;&#xff0c;从而支持对象创建的稳定。它是接口抽象之后的第一步工作。典型模式 Factory MethodAbstract …...

面试经典 150 题:20、2、228、122

20. 有效的括号 参考代码 #include <stack>class Solution { public:bool isValid(string s) {if(s.size() < 2){ //特判&#xff1a;空字符串和一个字符的情况return false;}bool flag true;stack<char> st; //栈for(int i0; i<s.size(); i){if(s[i] ( |…...

SQL面试题——持续增长问题

持续增长我们也可以称之为连续增长,本质上还是连续类的问题,前面我们已经介绍过 SQL面试题——最大连续登陆问题 SQL面试题——球员连续四次得分 SQL面试题——间隔连续问题 SQL面试题——蚂蚁SQL面试题 连续3天减少碳排放量不低于100的用户 你可以看看之前的文章,了解…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...