当前位置: 首页 > 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的用户 你可以看看之前的文章,了解…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...