日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Binder通信机制介绍

發布時間:2025/5/22 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Binder通信机制介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.Binder通信機制介紹

這篇文章會先對比Binder機制與Linux的通信機制的差別,了解為什么Android會另起爐灶,采用Binder。接著,會根據 Binder的機制,去理解什么是Service Manager,在C/S模型中扮演什么角色。最后,會從一次完整的通信活動中,去理解Binder通信的過程。

1.1 Android與Linux通信機制的比較

雖然Android繼承使用Linux的內核,但Linux與Android的通信機制不同。

在Linux中使用的IPC通信機制如下:

  • 傳統IPC:無名pipe, signal, trace, 有名管道

    ?

  • AT&T Unix?系統V:共享內存,信號燈,消息隊列

  • BSD Unix:Socket
  • 而在Android中,并沒有使用這些,取而代之的是Binder機制。Binder機制是采用OpenBinder演化而來,在Android中使用它的原因如下:

  • 采用C/S的通信模式。而在linux通信機制中,目前只有socket支持C/S的通信模式,但socket有其劣勢,具體參看第二條。

  • 有更好的傳輸性能。對比于Linux的通信機制,
    • socket:是一個通用接口,導致其傳輸效率低,開銷大;

    • 管道和消息隊列:因為采用存儲轉發方式,所以至少需要拷貝2次數據,效率低;

    • 共享內存:雖然在傳輸時沒有拷貝數據,但其控制機制復雜(比如跨進程通信時,需獲取對方進程的pid,得多種機制協同操作)。

    • 安全性更高。Linux的IPC機制在本身的實現中,并沒有安全措施,得依賴上層協議來進行安全控制。而Binder機制的 UID/PID是由Binder機制本身在內核空間添加身份標識,安全性高;并且Binder可以建立私有通道,這是linux的通信機制所無法實現的 (Linux訪問的接入點是開放的)。

    綜上所述,Android采用Binder機制是有道理的。既然Binder機制這么多優點,那么我們接下來看看它是怎樣通過C/S模型來實現的。

    ?

    1.2Binder在Service服務中的作用

    ?

    在android中,有很多Service都是通過binder來通信的,比如MediaServer旗下包含了眾多service:

    • AudioFlinger 音頻核心服務

    • AudioPolicyService:音頻策略相關的重要服務

    • MediaPlayerService:多媒體系統中的重要服務

    • CameraService:有關攝像/照相的重要服務

    Binder在C/S中的流程如下:

  • Server注冊服務。Server作為眾多Service的擁有者,當它想向Client提供服務時,得先去Service Manager(以后縮寫成SM)那兒注冊自己的服務。Server可以向SM注冊一個或多個服務。

  • Client申請服務。Client作為Service的使用者,當它想使用服務時,得向SM申請自己所需要的服務。Client可以申請一個或多個服務。

  • 當Client申請服務成功后,Client就可以使用服務了。
  • SM一方面管理Server所提供的服務,同時又響應Client的請求并為之分配相應的服務。扮演的角色相當于月老,兩邊牽線。這種通信方式的好處是: 一方面,service和Client請求便于管理,另一方面在應用程序開發時,只需為Client建立到Server的連接,就可花很少時間和精力去實 現Server相應功能。那么,Binder與這個通信模式有什么關系呢?!其實,3者的通信方式就是Binder機制(例如:Server向SM注冊服 務,使用Binder通信;Client申請請求,用的是Binder通訊)

    1.3Binder通信機制流程(整體框架)

    上圖即是Binder的通信模型。我們可以發現:

  • Client和Server是存在于用戶空間

  • Client與Server通信的實現,是由Binder驅動在內核空間實現

  • SM作為守護進程,處理客戶端請求,管理所有服務項。
  • 為了方便理解,我們可以把SM理解成DNS服務器; 那么Binder Driver 就相當于路由的功能。這里就涉及到Client和Server是如何通信的問題。下面對1.2中提到的3個流程進行說明。

    1.3.1 Server向SM注冊服務

  • 首先,XXXServer(XXX代表某個)在自己的進程中向Binder驅動申請創建一個XXXService的Binder的實體,

  • Binder驅動為這個XXXService創建位于內核中的Binder實體節點以及Binder的引用,注意,是將名字和新建的引用打包傳遞給SM(實體沒有傳給SM),通知SM注冊一個名叫XXX的Service。

  • SM收到數據包后,從中取出XXXService名字和引用,填入一張查找表中。

  • 此時,如果有Client向SM發送申請服務XXXService的請求,那么SM就可以在查找表中找到該Service的Binder引用,并把Binder引用(XXXBpBinder)返回給Client。
  • 在進一步了解Binder通信機制之前,我們先弄清幾個概念。

  • 引用和實體。這里,對于一個用于通信的實體(可以理解成具有真實空間的Object),可以有多個該實體的引用(沒有真實空間,可以理解成實體的 一個鏈接,操作引用就會操作對應鏈接上的實體)。如果一個進程持有某個實體,其他進程也想操作該實體,最高效的做法是去獲得該實體的引用,再去操作這個引 用。

  • 有些資料把實體稱為本地對象,引用成為遠程對象。可以這么理解:引用是從本地進程發送給其他進程來操作實體之用,所以有本地和遠程對象之名。
  • 1.3.2 一個問題-如何獲得SM的遠程接口

    如果你足夠細心,會發現這里有一個問題:

    Sm和Server都是進程,Server向SM注冊Binder需要進程間通信,當前實現的是進程間通信卻又用到進程間通信。這就好比雞生蛋、蛋生雞,但至少得先有其中之一。

    巧妙的Binder解決思路:

    針對Binder的通信機制,Server端擁有的是Binder的實體;Client端擁有的是Binder的引用。
    如果把SM看作Server端,讓它在Binder驅動一運行起來時就有自己的Binder實體(代碼中設置ServiceManager的Binder 其handle值恒為0)。這個Binder實體沒有名字也不需要注冊,所有的client都認為handle值為0的binder引用是用來與SM通信 的(代碼中是這么實現的),那么這個問題就解決了。那么,Client和Server中這么達成協議了(handle值為0的引用是專門與SM通信之用 的),還不行,還需要讓SM有handle值為0的實體才算大功告成。怎么實現的呢?!當一個進程調用Binder驅動時,使用 BINDER_SET_CONTEXT_MGR命令(在驅動的binder_ioctl中)將自己注冊成SM時,Binder驅動會自動為它創建 Binder實體。這個Binder的引用對所有的Client都為0。

    ?

    1.3.3 Client從SM獲得Service的遠程接口


    Server向SM注冊了Binder實體及其名字后,Client就可以通過Service的名字在SM的查找表中獲得該Binder的引用了 (BpBinder)。Client也利用保留的handle值為0的引用向SM請求訪問某個Service:我申請訪問XXXService的引用。 SM就會從請求數據包中獲得XXXService的名字,在查找表中找到該名字對應的條目,取出Binder的引用打包回復給client。之 后,Client就可以利用XXXService的引用使用XXXService的服務了。
    如果有更多的Client請求該Service,系統中就會有更多的Client獲得這個引用。

    1.3.4建立C/S通路后

    首先要理清一個概念:client擁有自己Binder的實體,以及Server的Binder的引用;Server擁有自己Binder的實體,以及Client的Binder的引用。我們也可以從接收方和發送方的方式來理解:

    • 從client向Server發數據:Client為發送方,擁有Binder的實體;Server為接收方,擁有Binder的引用

    • 從server向client發數據:Server為發送方,擁有Binder的實體;client為接收方,擁有Binder的引用。

    也就是說,我們在建立了C/S通路后,無需考慮誰是Client誰是Server,只要理清誰是發送方誰是接收方,就能知道Binder的實體和引用在哪邊。


    建立CS通路后的流程:(當接收方獲得Binder的實體,發送方獲得Binder的引用后)

  • 發送方會通過Binder實體請求發送操作。

  • Binder驅動會處理這個操作請求,把發送方的數據放入寫緩存(binder_write_read.write_buffer) (對于接收方為讀緩沖區),并把read_size(接收方讀數據)置為數據大小(對于具體的實現后面會介紹);

  • 接收方之前一直在阻塞狀態中,當寫緩存中有數據,則會讀取數據,執行命令操作

  • 接收方執行完后,會把返回結果同樣用binder_transaction_data結構體封裝,寫入寫緩沖區(對于發送方,為讀緩沖區)
  • 1.3.5 匿名Binder

    之前在介紹Android使用Binder機制的優點中,提到Binder可以建立點對點的私有通道,匿名Binder就是這種方式。在 Binder通信中,并不是所有用來通信的Binder實體都需要注冊給SM廣而告之的,Server可以通過已建立的實體Binder連接將創建的 Binder實體傳給Client。而這個Binder沒有向SM注冊名字。這樣Server與Client的通信就有很高的隱私性和安全性。

    這樣,整個Binder的通信流程就介紹完畢了,但是對于具體的代碼實現(比如binder_transaction_data是什 么?binder_write_read.write_buffer又是什么?具體的驅動和邏輯實現又是怎么樣?),在后面章節中會一一介紹。

    幾點疑問:
    1. 是誰,怎么樣成為SM守護進程,handle為0的binder實體什么時候創建?
    2. binder引用和實體是如何創建的?在驅動中如何實現的通信?
    3. 在SM中,binder實體是怎樣轉換成為引用的?
    4. Server是如何注冊服務,Client是如何獲取服務的?

    總結

    以上是生活随笔為你收集整理的Binder通信机制介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。