首页 > 其他分享 >一文简单了解Android中的input流程

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

时间:2024-11-13 22:51:14浏览次数:3  
标签:一文 InputReader 事件 Linux input Android event 输入 内核

在 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) {
    // 获取目标 Window
    sp targetWindow = getTargetWindow(event);
    // 将事件发送给目标 Window
    targetWindow->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

标签:一文,InputReader,事件,Linux,input,Android,event,输入,内核
From: https://blog.csdn.net/wudexiaoade2008/article/details/143753405

相关文章

  • 一文讲透Windows平台下的ASCII,Unicode编码问题
    ascii控制字符的编号范围是0-31和127(0x00-0x1F和0x7F),共33个字符。可显示字符编号范围是32-126(0x20-0x7E),共95个字符。((20241112221251-kkgxrg6"标准ASCII码对照表"))UNICODE美国人意识到他们应该提出一种标准方案来展示世界上所有语言中的所有字符,出于这个目的,Unicode诞......
  • 基于springboot+vue的Android的党员之家服务APP小程序(源码+文档+部署讲解等)
    课题简介本党员之家服务APP基于springboot+vue技术开发,专为Android平台设计,涵盖源码、文档和部署讲解,为党员们提供便捷、高效的服务。在资讯功能方面,APP会及时推送党的最新理论成果、政策解读、重要会议精神等内容,让党员能够第一时间了解党和国家的政治动态。同......
  • Android运行时请求权限封装
    @目录1介绍2测试用例设计3实现4用例测试5总结本文目的:“借助透明Activity封装一个易于调用的权限请求模块”1介绍Android权限的校验和申请比较简单,但在实际项目中使用时还要进行系统版本的适配,最不友好的是权限的申请结果需要在onRequestPermissionsResult中进行判断,如......
  • Rust 在 Android 的编程实践——技术驱动的车云一体化解决方案探索
    Greptime车云一体化解决方案颠覆了从前传统的车云协同模式,采用更加低成本、高效率的方案来满足当前的市场需求。其中GreptimeDBEdge作为核心组件,专为车机环境量身打造。本文旨在详尽探讨在Android平台利用Rust语言进行开发过程中所积累的经验和教训。交叉编译在车机场景......
  • 一文学会,利用LLaMA 3.2打造能“识图断字”的个人AI助理
    人工智能最直接也是最普及的应用之一肯定是聊天机器人,或者叫个人AI助理。尽管聊天机器人以各种形式存在了30年,但在过去两年中,这些个人AI助理才真正成为热门应用。它们已经从前沿技术范畴落地到生活的各个方面、社交场合和商业场景中。虽然它们接入门槛低且易于使用,你打开......
  • Android OpenGL ES详解——立方体贴图
    目录一、概念二、如何使用1、创建立方体贴图2、生成纹理3、设置纹理环绕和过滤方式4、激活和绑定立方体贴图三、应用举例——天空盒1、概念2、加载天空盒3、显示天空盒4、优化四、应用举例——环境映射:反射五、应用举例——环境映射:折射六、应用举例——动态......
  • Android SIM 解锁:如何轻松解锁 Android 上的 SIM 卡
    您的Android手机SIM卡是否已锁定?许多人购买Android手机时并不知道手机是否已锁定SIM卡。您可能想要更改网络服务提供商,但后来发现新的SIM卡无法在Android手机上使用。这会带来不便,因为您无法通过其他线路使用购买的电话。人们可能会问自己,如果遇到此问题,如何在An......
  • 高手技巧:如何在 Android 上绕过人脸识别
    人脸识别是Android引入的一项重要安全功能,可帮助用户保护其设备免遭未经授权的访问。如果您想保证文件安全,它非常有用。通常,面部识别的工作原理是使用您的面部作为生物识别标识符来验证某些操作。但是,有时会由于各种原因而失败。可能是相机坏了,或者设备有问题。发生这种情况......
  • 如何解锁碎屏手机(Android 指南)
    一般来说,电子设备很脆弱,除非它们是为大量使用而设计的。Android智能手机、平板电脑和智能手表也存在这种脆弱性。Android智能手机或平板电脑的触摸屏是您访问和使用手机的最重要部件之一。如果屏幕在锁定时破裂或破裂,肯定会令人不安。您将陷入如何解锁屏幕破损的手机的困......
  • App WebView白屏检测及解决总结,包括Android 和 iOS
    App上WebView白屏在移动端上场景的H5页面白屏问题,根据平台分为Android和ios端上H5白屏问题(相关解决和优化基于移动端侧)之前在自己博客发布过,最近有做朋友问就再发出来下,希望能帮助更多人,重要的是了解白屏问题的原理和解决思路。Android的的白屏问题表现现对比较多些,按问题......