Android7 Input(六)InputChannel

概述:

本文講述Android Input輸入框架中 InputChannel的功能。從前面的講述,我們知道input系統服務最終將輸入事件寫入了InputChannel,而input屬于system_server進程,App屬于另外一個進程,當Input系統服務想要把事件傳遞給App進行處理時這里就涉及到了一個跨進程通信的問題。Android系統中常用的就是通過Binder實現進程間通信,但是Binder屬于CS架構,單一的連接不能實現Client和Server的雙向通信,如果我們想要實現進程間的雙向通信,則必須建立兩個Binder通道。Android系統有多個App 這樣則每個App都需要兩個Binder通信通道才能完成Input系統進行通信。這顯然不是很好的選擇, 所以Android系統的Input框架選擇了傳統Linux的Unix域通信機制,也就是我們本章講述的InputChannel實現原理。

本文涉及的源碼路徑

frameworks/native/libs/input/InputTransport.cpp

frameworks/base/core/java/android/view/InputChannel.java

frameworks/base/core/jni/android_view_InputChannel.cpp

InputChannel類

public final class InputChannel implements Parcelable {private static final String TAG = "InputChannel";......@SuppressWarnings("unused")private long mPtr; // used by native codeprivate static native InputChannel[] nativeOpenInputChannelPair(String name);    private native void nativeDispose(boolean finalized);private native void nativeTransferTo(InputChannel other);private native void nativeReadFromParcel(Parcel parcel);private native void nativeWriteToParcel(Parcel parcel);private native void nativeDup(InputChannel target);private native String nativeGetName();......public InputChannel() {}@Overrideprotected void finalize() throws Throwable {try {nativeDispose(true);} finally {super.finalize();}}......public static InputChannel[] openInputChannelPair(String name) {if (name == null) {throw new IllegalArgumentException("name must not be null");}if (DEBUG) {Slog.d(TAG, "Opening input channel pair '" + name + "'");}return nativeOpenInputChannelPair(name);}public String getName() {String name = nativeGetName();return name != null ? name : "uninitialized";}......public void dispose() {nativeDispose(false);}......public void transferTo(InputChannel outParameter) {if (outParameter == null) {throw new IllegalArgumentException("outParameter must not be null");}nativeTransferTo(outParameter);}......
}

1、從java層的InputChannel類可以看出,該類的核心實現都是由native jni層完成的。因此接下來我們主要從Native層講述InputChannel的實現原理;

2、mPtr 保存native層對應的對象地址;

3、可序列化,InputChannel對象可以跨組件傳遞;

InputChannel 方法

由于我們本系列的博客講述Android Input輸入管理框架,下面的講述中,只講述設計到Input輸入管理的關鍵方法實現。

1、openInputChannelPair

openInputChannelPair的實現如下所示:

 public static InputChannel[] openInputChannelPair(String name) {......return nativeOpenInputChannelPair(name);}

該方法本質上直接調用了jni方法nativeOpenInputChannelPair,如下所示:

static jobjectArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* env,jclass clazz, jstring nameObj) {......sp<InputChannel> serverChannel;sp<InputChannel> clientChannel;status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);......// 創建兩個InputChannel 空java對象jobjectArray channelPair = env->NewObjectArray(2, gInputChannelClassInfo.clazz, NULL);if (env->ExceptionCheck()) {return NULL;}jobject serverChannelObj = android_view_InputChannel_createInputChannel(env,new NativeInputChannel(serverChannel));if (env->ExceptionCheck()) {return NULL;}jobject clientChannelObj = android_view_InputChannel_createInputChannel(env,new NativeInputChannel(clientChannel));if (env->ExceptionCheck()) {return NULL;}// 初始化數組對象env->SetObjectArrayElement(channelPair, 0, serverChannelObj);env->SetObjectArrayElement(channelPair, 1, clientChannelObj);// 返回創建的2個java層對象return channelPair;
}

nativeOpenInputChannelPair方法主要完成如下的邏輯:

1、創建一個網絡socket對套接字,分別由serverChannel和clientChannel進行管理,這部分源碼不再展開詳細講解;

2、創建java層的InputChannel兩個數組對象;

3、創建serverChannel和clientChannel InputChannel 對象,并分別設置server和client的native層的對象地址;

4、初始化第2步創建的java數組對象,然后將該數組對象返回java空間;

2、transferTo

transferTo的方法實現如下所示:

public void transferTo(InputChannel outParameter) {......nativeTransferTo(outParameter);}

改方法直接調用了nativeTransferTo,如下所示:

/*** 將自己的native C++對象綁定給otherObj的native C++上,然后清空自己的native對象*/
static void android_view_InputChannel_nativeTransferTo(JNIEnv* env, jobject obj,jobject otherObj) {if (android_view_InputChannel_getNativeInputChannel(env, otherObj) != NULL) {jniThrowException(env, "java/lang/IllegalStateException","Other object already has a native input channel.");return;}// 獲的調用對象的native對象地址NativeInputChannel* nativeInputChannel =android_view_InputChannel_getNativeInputChannel(env, obj);// 將otherObj對象的native地址設置為調用對象的nativeInputChannelandroid_view_InputChannel_setNativeInputChannel(env, otherObj, nativeInputChannel);// 清空調用對象的native對象地址android_view_InputChannel_setNativeInputChannel(env, obj, NULL);
}

nativeTransferTo的實現邏輯細節,我們不再展開描述,該方法的主要功能就是將otherObj 對象的native層的C++地址替換為調用該方法的InputChannel對象的native層的地址;

3、dispose

dispose的實現方法,如下所示:

 public void dispose() {nativeDispose(false);}

該方法也是直接調用native方法,如下所示:

static void android_view_InputChannel_nativeDispose(JNIEnv* env, jobject obj, jboolean finalized) {NativeInputChannel* nativeInputChannel =android_view_InputChannel_getNativeInputChannel(env, obj);if (nativeInputChannel) {if (finalized) {ALOGW("Input channel object '%s' was finalized without being disposed!",nativeInputChannel->getInputChannel()->getName().string());}nativeInputChannel->invokeAndRemoveDisposeCallback(env, obj);android_view_InputChannel_setNativeInputChannel(env, obj, NULL);// 刪除C++對象delete nativeInputChannel;}
}

該方法的實現細節,我們不再展開描述,它的主要功能就是釋放native層的InputChannel對象。

總結

本文為Android Input框架中App和Input 服務進行通信的橋梁InputChannel,本質上就是就是對linux中unix域 Socket進程間通信的封裝,Framework層調用java層的InputChannel方法,而該方法的核心實現都處于native層。下一篇講述App如何使用InputChannel與input系統服務建立鏈接。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/905295.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/905295.shtml
英文地址,請注明出處:http://en.pswp.cn/news/905295.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【 Redis | 實戰篇 秒殺實現 】

目錄 前言&#xff1a; 1.全局ID生成器 2.秒殺優惠券 2.1.秒殺優惠券的基本實現 2.2.超賣問題 2.3.解決超賣問題的方案 2.4.基于樂觀鎖來解決超賣問題 3.秒殺一人一單 3.1.秒殺一人一單的基本實現 3.2.單機模式下的線程安全問題 3.3.集群模式下的線程安全問題 前言&…

如何用URDF文件構建機械手模型并與MoveIt集成

機械手URDF文件的編寫 我們用urdf文件來描述我們的機械手的外觀以及物理性能。這里為了簡便&#xff0c;就只用了基本的圓柱、立方體了。追求美觀的朋友&#xff0c;還可以用dae文件來描述機械手的外形。 import re def remove_comments(text):pattern r<!--(.*?)-->…

《構建社交應用的安全結界:雙框架對接審核API的底層邏輯與實踐》

用戶生成內容如潮水般涌來。從日常的生活分享&#xff0c;到激烈的觀點碰撞&#xff0c;這些內容賦予社交應用活力&#xff0c;也帶來管理難題。虛假信息、暴力言論、侵權內容等不良信息&#xff0c;如同潛藏的暗礁&#xff0c;威脅著社交平臺的健康生態。內容審核機制&#xf…

39:分類器流程

第一步 創建支持向量機分類器 create_class_svm (7, rbf, KernelParam, Nu, |ClassNames|, one-versus-one, principal_components, 5, SVMHandle) 第二步 添加樣本到分類器里 for ClassNumber : 0 to |ClassNames| - 1 by 1 *列出目錄下的所有文件 list_files (ReadPath…

LangChain對話鏈:打造智能多輪對話機器人

LangChain對話鏈:打造智能多輪對話機器人 目錄 LangChain對話鏈:打造智能多輪對話機器人ConversationChain 是什么核心功能與特點基本用法示例內存機制自定義提示詞應用場景與其他鏈的結合`SequentialChain` 是什么![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/0…

el-select 結合 el-tree:樹形下拉數據

一、單選 <template><div class"selectTree-wapper"><el-selectv-model"selectValue"placeholder"請選擇"popper-class"custom-el-select-class"ref"selectRef"clearableclear"clearHandle">&…

BFS算法篇——從晨曦到星辰,BFS算法在多源最短路徑問題中的詩意航行(下)

文章目錄 引言一、01矩陣1.1 題目鏈接&#xff1a;https://leetcode.cn/problems/01-matrix/description/1.2 題目分析&#xff1a;1.3 思路講解&#xff1a;1.4 代碼實現&#xff1a; 二、飛地的數量2.1 題目鏈接&#xff1a;https://leetcode.cn/problems/number-of-enclaves…

Leetcode (力扣)做題記錄 hot100(49,136,169,20)

力扣第49題&#xff1a;字母異位詞分組 49. 字母異位詞分組 - 力扣&#xff08;LeetCode&#xff09; 遍歷數組&#xff0c;將每一個字符串變成char數組 然后排序&#xff0c;如果map里面有則將他的值返回來&#xff08;key是排序好的字符串&#xff09; class Solution {pu…

【自學30天掌握AI開發】第1天 - 人工智能與大語言模型基礎

自學30天掌握AI開發 - 第1天 &#x1f4c6; 日期和主題 日期&#xff1a;第1天 主題&#xff1a;人工智能與大語言模型基礎 &#x1f3af; 學習目標 了解人工智能的發展歷史和基本概念掌握大語言模型的基本原理和工作機制區分不同類型的AI模型及其特點理解AI在當前社會中的…

WebRTC 源碼原生端Demo入門-1

1、概述 我的代碼是比較新的&#xff0c;基于webrtc源碼倉庫的main分支的&#xff0c;在windows下把源碼倉庫下載好了后&#xff0c;用visual stdio 2022打開進行編譯調試src/examples/peerconnection_client測試項目,主要是跑通這個demo來入手和調試&#xff0c;純看代碼很難…

【LeetCode】刪除排序數組中的重復項 II

題目 鏈接 思路 雙指針 我好聰明啊&#xff0c;自己想出了這個雙指針的辦法&#xff0c;哈哈哈哈哈哈哈&#xff0c;太高興了 代碼 class Solution(object):def removeDuplicates(self, nums):""":type nums: List[int]:rtype: int"""nlen…

通義千問席卷日本!開源界“卷王”阿里通義千問成為日本AI發展新基石

據日本經濟新聞&#xff08;NIKKEI&#xff09;報道&#xff0c;通義千問已成為日本AI開發的新基礎&#xff0c;其影響力正逐步擴大&#xff0c;深刻改變著日本AI產業的格局。 同時&#xff0c;日本經濟新聞將通義千問Qwen2.5-Max列為全球AI模型綜合評測第六名&#xff0c;不僅…

第J7周:對于ResNeXt-50算法的思考

目錄 思考 一、代碼功能分析 1. 構建 shortcut 分支&#xff08;殘差連接的旁路&#xff09; 2. 主路徑的第一層卷積&#xff08;11&#xff09; 4. 主路徑的第三層卷積&#xff08;11&#xff09; 5. 殘差連接 激活函數 二、問題分析總結&#xff1a;殘差結構中通道數不一致的…

如何解決Jmeter中的亂碼問題?

在 JMeter 中遇到亂碼問題通常是由于字符編碼不一致導致的&#xff0c;常見于 HTTP 請求響應、參數化文件讀取、報告生成等場景。以下是系統化的解決方案&#xff1a; 1. HTTP 請求響應亂碼 原因&#xff1a; 服務器返回的字符編碼&#xff08;如UTF-8、GBK&#xff09;與 J…

# YOLOv2:目標檢測的升級之作

YOLOv2&#xff1a;目標檢測的升級之作 在目標檢測領域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;系列算法以其高效的速度和創新的檢測方式受到了廣泛關注。今天&#xff0c;我們就來深入探討一下 YOLOv2&#xff0c;看看它是如何在繼承 YOLOv1 的基礎上進行…

小白入!WiFi 技術大解析

WiFi&#xff0c;全稱Wireless Fidelity&#xff0c;是一種無線局域網技術&#xff0c;允許電子設備通過無線電波連接到互聯網。以下是對WiFi的一些介紹&#xff1a; 一、基本概述 定義&#xff1a;WiFi是一種基于IEEE 802.11標準系列的無線局域網技術&#xff0c;使設備能夠…

【prometheus+Grafana篇】基于Prometheus+Grafana實現windows操作系統的監控與可視化

&#x1f4ab;《博主主頁》&#xff1a; &#x1f50e; CSDN主頁 &#x1f50e; IF Club社區主頁 &#x1f525;《擅長領域》&#xff1a;擅長阿里云AnalyticDB for MySQL(分布式數據倉庫)、Oracle、MySQL、Linux、prometheus監控&#xff1b;并對SQLserver、NoSQL(MongoDB)有了…

推薦一個感覺非常好的文章,是知識圖譜的

為了省瀏覽的事兒&#xff0c;以后打算寫文章都短一些&#xff0c;這樣不用被強制登錄、關注了 正文 鏈接是 https://blog.csdn.net/Appleyk/article/details/80422055 放個截圖 推薦理由 兩個&#xff0c;第一內容確實硬核。第二算是緣分吧&#xff0c;我之前公司好像&am…

《企業級前端部署方案:Jenkins+MinIO+SSH+Gitee+Jenkinsfile自動化實踐》

文章目錄 前言前端項目CICD時序圖一、環境準備1、服務器相關2、Jenkins憑據3、注意事項 二、設計思想1. 模塊化設計2.多環境支持3. 制品管理4. 安全部署機制5. 回滾機制 三、CI階段1、構建節點選擇2、代碼拉取3、代碼編譯4、打包并上傳至minio 四、CD階段五、回滾階段六、構建通…

Go語言超時控制方案全解析:基于goroutine的優雅實現

一、引言 在構建高可靠的后端服務時&#xff0c;超時控制就像是守護系統穩定性的"安全閥"&#xff0c;它確保當某些操作無法在預期時間內完成時&#xff0c;系統能夠及時止損并釋放資源。想象一下&#xff0c;如果沒有超時控制&#xff0c;一個簡單的數據庫查詢卡住…