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
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82711.shtml
英文地址,請注明出處:http://en.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&…