最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

圖文結合:通俗易懂的Android多進程間通信--binder機制

2022-09-13 22:00 作者:初壹十五阿  | 我要投稿

一丶Android多進程通信的應用場景?

  • ?;?/p>

  • webview

  • 加載圖片

  • push推送

  • 與系統服務通信

部分參考,包含Framework專題

1.騰訊Android開發(fā)筆記
2.2022年Android十一位大廠面試真題
3.60道音視頻經典面試題

二丶為什么要用binder

  • Android系統內核是Linux內核

  • Linux內核進程通信有:管道、內存共享、Socket、File;

  • 對比:


Binder的一次拷貝發(fā)生在用戶空間拷貝到內核空間;

用戶空間:?App進程運行的內存空間;

內核空間:?系統驅動、和硬件相關的代碼運行的內存空間,也就是進程ID為0的進程運行的空間;

程序局部性原則:?只加載少量代碼;應用沒有運行的代碼放在磁盤中,運行時高速緩沖區(qū)進行加載要運行的代碼;默認一次加載一個頁(4K),若不夠4K就用0補齊;

MMU:內存管理單元;

CPU提供虛擬地址;

當對變量操作賦值時:

  • CPU拿著虛擬地址和值給到MMU

  • MMU用虛擬地址匹配到物理地址,MMU去物理內存中進行賦值;

物理地址:?物理內存的實際地址,并不是磁盤;

虛擬地址:?MMU根據物理內存的實際地址翻譯出的虛擬地址;提供給CPU使用;


頁命中:CPU讀取變量時,MMU在物理內存的頁表中找到了這個地址;

頁未命中:CPU讀取變量時,MMU在物理內存的頁表中沒有找到了這個地址,此時會觸發(fā)MMU去磁盤讀取變量并存到物理內存中;

普通的二次拷貝:

應用A拷貝到服務端:coay_from_user

從服務端拷貝到應用B:coay_to_user

mmap():

  • 在物理內存中開辟一段固定大小的內存空間

  • 將磁盤文件與物理內存進行映射(理解為綁定)

  • MMU將物理內存地址轉換為虛擬地址給到CPU(虛擬地址映射物理內存)

共享內存進程通信:

  • 進程A調用mmap()函數會在內核空間中虛擬地址和一塊同樣大小的物理內存,將兩者進行映射

  • 得到一個虛擬地址

  • 進程B調用mmap()函數,傳參和步驟1一樣的話,就會得到一個和步驟2相同的虛擬地址

  • 進程A和進程B都可以用同一虛擬地址對同一塊映射內存進行操作

  • 進程A和進程B就實現了通信

  • 沒有發(fā)生拷貝,共享一塊內存,不安全

Binder通信原理:

角色:Server端A、Client端B、Binder驅動、內核空間、物理內存

  • Binder驅動在物理內存中開辟一塊固定大?。?M-8K)的物理內存w,與內核空間的虛擬地址x進行映射得到

  • A的用戶空間的虛擬地址ax和物理內存w進行映射

  • 此時內核空間虛擬地址x和物理內存w已經進行了映射,物理內存w和Server端A的用戶空間虛擬地址ax進行了映射:也就是 內核空間的虛擬地址x = 物理內存w = Server端A的用戶空間虛擬地址ax

  • B發(fā)送請求:將數據按照binder協議進行打包給到Binder驅動,Binder驅動調用coay_from_user()將數據拷貝到內核空間的虛擬地址x

  • 因步驟3中的三塊區(qū)域進行了映射

  • Server端A就得到了Client端B發(fā)送的數據

  • 通過內存映射關系,只發(fā)生了一次拷貝


Activity跳轉時,最多攜帶1M-8k(1兆減去8K)的數據量;

真實數據大小為:1M內存-兩頁的請求頭數據=1M-8K;

應用A直接將數據拷貝到應用B的物理內存空間中,數據量不能超過1M-8K;拷貝次數少了一次,少了從服務端拷貝到用戶;

IPC通信機制:

  • 服務注冊

  • 服務發(fā)現

  • 服務調用

以下為簡單的主進程和子進程通信:

1、服務注冊: 緩存中心中有三張表(暫時理解為三個HashMap,Binder用的是native的紅黑樹):

  • 第一種:放key?:String - value:類的Class

  • 第二種:放key?:Class的類名 - value:類的方法集合;

  • 第三種:放key?:Class的類名 - value:類的對象;

類的方法集合:key-value;

key:方法簽名:“方法名” 有參數時用 “方法名-參數類型-參數類型-參數類型......”;

value: 方法本身;

注冊后,服務若沒被調用則一直處于沉默狀態(tài),不會占用內存,這種情況只是指用戶進程里自己創(chuàng)建的服務,不適用于AMS這種;

2、服務發(fā)現: 當被查詢到時,要被初始化;

  • 客戶端B通過發(fā)送信息到服務端A

  • 服務端解析消息,反序列化

  • 通過反射得到消息里的類名,方法,從注冊時的第一種、第二種表里找到Class,若對象沒初始化則初始化對象,并將對象添加到第三種的表里;

3、服務調用:

  • 使用了動態(tài)代理

  • 客戶端在服務發(fā)現時,拿到對象(其實是代理)

  • 客戶端調用對象方法

  • 代理發(fā)送序列化數據到服務端A

  • 服務端A解析消息,反序列化,得到方法進行處理,得到序列化數據結果

  • 將序列化結果寫入到客戶端進程的容器中;

  • 回調給客戶端

AIDL?BpBinder:數據發(fā)送角色 BbBinder:數據接收角色


編譯器生成的AIDL的java接口.Stub.proxy.transact()為數據發(fā)送處;

發(fā)送的數據包含:數據+方法code+方法參數等等;

  • 發(fā)送時調用了Linux的驅動

  • 調用copy_from_user()拷貝用戶發(fā)送的數據到內核空間

  • 拷貝成功后又進行了一次請求頭的拷貝:copy_from_user()

  • 也就是把一次的數據分為兩次拷貝

請求頭:包含了目的進程、大小等等參數,這些參數占了8K

編譯器生成的AIDL的java接口.Stub.onTransact()為數據接收處;

Binder中的IPC機制:

  • 每個App進程啟動時會在內核空間中映射一塊1M-8K的內存

  • 服務端A的服務注冊到ServiceManager中:服務注冊

  • 客戶端B想要調用服務端A的服務,就去請求ServiceManager

  • ServiceManager去讓服務端A實例化服務:服務發(fā)現

  • 返回一個用來發(fā)送數據的對象BpBinder給到客戶端B

  • 客戶端B通過BpBinder發(fā)送數據到服務端A的內核的映射區(qū)域(傳參時客戶端會傳一個reply序列化對象,在底層會將這個地址一層一層往下傳,直至傳到回調客戶端):這里發(fā)生了一次通信copy_from_user:服務調用

  • 服務端A通過BBBinder得到數據并處理數據

  • 服務端喚醒客戶端等待的線程;將返回結果寫入到客戶端發(fā)送請求時傳的一個reply容器地址中,調用onTransact返回;

  • 客戶端在onTransac中得到數據;通信結束;

ServiceManager維持了Binder這套通信框架;

三丶APP多進程的優(yōu)點

  • 擴大應用可使用的內存
    手機內存6G,系統分配給虛擬機的內存一般32M、48M、64M,使用多進程時,可以使用一個進程專門加載圖片,防止OOM

  • 子進程崩潰,不會導致主進程崩潰

  • 互相保活,即如果子進程被系統kill掉時,主進程拉起子進程。主進程被系統kill掉時,子進程拉起主進程。

四丶多進程通信原理


Android進程是運行在系統分配的虛擬地址空間,虛擬地址空間分為用戶空間和內核空間。多進程間,用戶空間不共享,內核空間共享,進程間通過共享的內核空間通信。

五丶多進程通信有哪些方式?

1.傳統的IPC方式:socket,內存共享。
2.Android特有的方式:Binder。

六丶Binder相對其他IPC方式優(yōu)點/為什么使用Binder?


1.性能:

A.Socket傳輸數據的過程:兩次拷貝



B.Binder傳輸數據的過程:一次拷貝



內存映射:MMAPmemory map

虛擬內存和物理內存

虛擬內存映射到物理內存,物理內存存儲數據。

2.易用性

3.安全性

七丶Binder在Android系統CS通信機制中起到的作用

  • Android C/S通信機制


  • Binder機制的關鍵概念


  • BinderAndroid CS通信機制中起到的作用


AIDLBinder的關系?
AIDL封裝了Binder,AIDL調用Binder

部分參考,包含Framework專題

1.騰訊Android開發(fā)筆記
2.2022年Android十一位大廠面試真題
3.60道音視頻經典面試題


圖文結合:通俗易懂的Android多進程間通信--binder機制的評論 (共 條)

分享到微博請遵守國家法律
筠连县| 视频| 京山县| 嘉黎县| 乌苏市| 鹤岗市| 大渡口区| 普兰县| 庆云县| 高密市| 合肥市| 阿鲁科尔沁旗| 嘉善县| 资源县| 寻甸| 万荣县| 建德市| 海安县| 香河县| 和龙市| 苍山县| 思茅市| 文登市| 晋城| 弥渡县| 苍南县| 永靖县| 龙南县| 宽甸| 三亚市| 临汾市| 理塘县| 山西省| 遂溪县| 阳曲县| 乐亭县| 聊城市| 牟定县| 集贤县| 珲春市| 怀仁县|