1. 程式人生 > >[Android] 徹底瞭解Binder機制原理和底層實現

[Android] 徹底瞭解Binder機制原理和底層實現

1.Binder通訊機制介紹

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

1.1 Android與Linux通訊機制的比較

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

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

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

  2. AT&T Unix 系統V:共享記憶體,訊號燈,訊息佇列

  3. BSD Unix:Socket

而在Android中,並沒有使用這些,取而代之的是Binder機制。Binder機制是採用OpenBinder演化而來,在Android中使用它的原因如下:

  1. 採用C/S的通訊模式。而在linux通訊機制中,目前只有socket支援C/S的通訊模式,但socket有其劣勢,具體參看第二條。

  2. 有更好的傳輸效能。對比於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中的流程如下:

\

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

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

  3. 當Client申請服務成功後,Client就可以使用服務了。

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

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

\

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

  1. Client和Server是存在於使用者空間

  2. Client與Server通訊的實現,是由Binder驅動在核心空間實現

  3. SM作為守護程序,處理客戶端請求,管理所有服務項。

為了方便理解,我們可以把SM理解成DNS伺服器; 那麼Binder Driver 就相當於路由的功能。這裡就涉及到Client和Server是如何通訊的問題。下面對1.2中提到的3個流程進行說明。

1.3.1 Server向SM註冊服務

\

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

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

  3. SM收到資料包後,從中取出XXXService名字和引用,填入一張查詢表中。

  4. 此時,如果有Client向SM傳送申請服務XXXService的請求,那麼SM就可以在查詢表中找到該Service的Binder引用,並把Binder引用(XXXBpBinder)返回給Client。

在進一步瞭解Binder通訊機制之前,我們先弄清幾個概念。

  1. 引用和實體。這裡,對於一個用於通訊的實體(可以理解成具有真實空間的Object),可以有多個該實體的引用(沒有真實空間,可以理解成實體的 一個連結,操作引用就會操作對應連結上的實體)。如果一個程序持有某個實體,其他程序也想操作該實體,最高效的做法是去獲得該實體的引用,再去操作這個引 用。

  2. 有些資料把實體稱為本地物件,引用成為遠端物件。可以這麼理解:引用是從本地程序傳送給其他程序來操作實體之用,所以有本地和遠端物件之名。

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的引用後)

  1. 傳送方會通過Binder實體請求傳送操作。

  2. Binder驅動會處理這個操作請求,把傳送方的資料放入寫快取(binder_write_read.write_buffer) (對於接收方為讀緩衝區),並把read_size(接收方讀資料)置為資料大小(對於具體的實現後面會介紹);

  3. 接收方之前一直在阻塞狀態中,當寫快取中有資料,則會讀取資料,執行命令操作

  4. 接收方執行完後,會把返回結果同樣用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是如何獲取服務的?

相關推薦

[Android] 徹底瞭解Binder機制原理底層實現

1.Binder通訊機制介紹 這篇文章會先對比Binder機制與Linux的通訊機制的差別,瞭解為什麼Android會另起爐灶,採用Binder。接著,會根據 Binder的機制,去理解什麼是Service Manager,在C/S模型中扮演什麼角色。最後,會從一次完整的通訊活動中,去理解Binder通訊

徹底瞭解Binder機制原理底層實現

轉載地址: http://www.2cto.com/kf/201606/515548.html http://www.2cto.com/kf/201606/515548.html 1.Binder通訊機制介紹 這篇文章會先對比Binder機制與Linux的通訊機制的

HashTable原理底層實現

1. 概述 上次討論了HashMap的結構,原理和實現,本文來對Map家族的另外一個常用集合HashTable進行介紹。HashTable和HashMap兩種集合非常相似,經常被各種面試官問到兩者的區別。 對於兩者的區別,主要有以下幾點: HashMap是非同步的,

LinkedHashMap原理底層實現

1.概述 在使用HashMap的時候,可能會遇到需要按照當時put的順序來進行雜湊表的遍歷。通過上篇對HashMap的瞭解,我們知道HashMap中不存在儲存順序的機制。本篇文章要介紹的LinkedHashMap專為此特性而生。在LinkedHashMap中可以保持兩種順序

Android進階——效能優化之佈局渲染原理底層機制詳解(四)

引言 UI 全稱User Interaction,我第一次聽到這個名詞是在大學的時候,當時候上人機互動課,我們教授說他認為iPhone的i 就是代表Interaction的意思,暫且不必爭辯是非。回到我們軟體開發中來,UI是使用者感知與互動的第一且唯一的途徑,

Java並發機制底層實現原理

差距 32處理器 們的 trac 結點 exce jdk cep 定性   Java代碼在編譯後會變成Java字節碼,字節碼被類加載器加載到JVM裏,JVM執行字節碼轉化為匯編指令在CPU上執行。Java中的並發機制依賴於JVM的實現和CPU的指令。      Java語言

Android Binder機制原理

Binder是Android系統程序間通訊(IPC)方式之一。Linux已經擁有的程序間通訊IPC手段包括(Internet Process Connection): 管道(Pipe)、訊號(Signal)和跟蹤(Trace)、插口(Socket)、報文佇列(Messag

Android跨程序通訊:binder機制原理

個人閱讀收穫 通過binder驅動我們可以減少一次io操作,從而減少了我們程序通訊的花費的資源,加快了程序間通訊的速度。我們使用到了Linux的mmap()操作,從而實現了程序間的接收快取區與程序的空間區的對映,從而少了一次io操作。我們的客戶端會發送資訊通過我們io操作講

Android Binder機制原理(史上最強理解,沒有之一)(轉)

Binder是Android系統程序間通訊(IPC)方式之一。Linux已經擁有的程序間通訊IPC手段包括(Internet Process Connection): 管道(Pipe)、訊號(Signal)和跟蹤(Trace)、插口(Socket)、報文佇列(Messag

Android - Binder機制 - ProcessStateIPCThreadState

以下幾篇文章是較深入分析binder機制。 目錄 1. Android - Binder機制 - ServiceManager 2. Android - Binder機制 - 普通service註冊 3. Android - Binder機制 - 獲得普通service 4. A

Android Binder機制原理(史上最強理解,沒有之一)

Binder是Android系統程序間通訊(IPC)方式之一。Linux已經擁有的程序間通訊IPC手段包括(Internet Process Connection): 管道(Pipe)、訊號(Signal)和跟蹤(Trace)、插口(Socket)、報文佇列(Messa

Android Handler 消息機制原理解析

當前 its leak 示例 異步消息 了解 modifier supported 異步 前言 做過 Android 開發的同學都知道,不能在非主線程修改 UI 控件,因為 Android 規定只能在主線程中訪問 UI ,如果在子線程中訪問 UI ,那麽程序就會拋出異常 a

JMM底層實現原理

現代計算機物理上的記憶體模型 物理機遇到的併發問題與虛擬機器中的情況有不少相似之處,物理機對併發的處理方案對於虛擬機器的實現也有相當大的參考意義。 其中一個重要的複雜性來源是絕大多數的運算任務都不可能只靠處理器“計算”就能完成,處理器至少要與記憶體互動,如讀取運算資料、儲存運算結果

HashMap的實現原理底層結構 圖解+原始碼分析

 雜湊表(hash table)也叫散列表,是一種非常重要的資料結構,應用場景及其豐富,許多快取技術(比如memcached)的核心其實就是在記憶體中維護一張大的雜湊表,而HashMap的實現原理也常常出現在各類的面試題中,重要性可見一斑。本文會對java集合框架中的對應實現HashMap的實現原理

Android View 的事件分發原理滑動衝突分析

作為一名Android 開發者,每天接觸最多的就是 View 了。Android View 雖然不是四大元件,但其並不比四大元件的地位低。而 View 的核心知識點事件分發機制則是不少剛入門同學的攔路虎,也是面試過程中基本上都會問的。理解 View 的事件能夠讓你寫出更好自定義 View 以及解決滑動衝突。

HashMap的實現原理底層結構

memcached 結點 文章 actor lse get方法 會有 power 整體 哈希表(hash table)也叫散列表,是一種非常重要的數據結構,應用場景及其豐富,許多緩存技術(比如memcached)的核心其實就是在內存中維護一張大的哈希表,而HashMap的實

面試題 —— HashMap、HashTable、HashSet的實現原理底層資料結構

HashMap和Hashtable的區別 兩者最主要的區別在於Hashtable是執行緒安全,而HashMap則非執行緒安全 Hashtable的實現方法裡面都添加了synchronized關鍵字來確保執行緒同步,因此相對而言HashMap效能會高一些,我們平時使

Android 深入淺出之Binder機制

轉自:http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html Android深入淺出之Binder機制 一說明  Android系統最常見也是初學者最難搞明白的就是Binder了,很多很多的Service

HashMapHashSet原理底層實現

HashMap底層用雜湊演算法實現,下面看一下雜湊算表的整體概括: 當map.put(“key”,”values”);的時候,底層是這樣的: static final Entry<?,?>[] EMPTY_TABLE = {}; transient E

瞭解Binder機制(極簡主義解釋風格)

Binder 這個問題很多文章都有解釋,比如:Binder是Android跨程序通訊方式,它實現了IBinder介面,是ServiceManager連線各種Manager(如WindowManager、ActivityManager等)的橋樑。但是我覺得這些說