寫給App開發的Binder原理系列

前言

Binder原理是掌握系統底層原理的基石,也是進階高級工程師的必備知識點,這篇文章不會過多介紹Binder原理,而是講解學習Binder前須要的掌握的知識點。android

我認爲學好Binder原理的祕訣主要有兩點:面試

  1. 瞭解Binder原理涉及的前置知識點,好比Linux的IPC機制種類等知識點。
  2. 將Binder原理分爲幾個部分,各個擊破。

本篇文章的目的就是幫助你們完成第1點,第二點會在後續的系列文章進行詳細介紹。緩存

1.Linux和Android的IPC機制種類

IPC全名爲inter-Process Communication,含義爲進程間通訊,是指兩個進程之間進行數據交換的過程。在Android和Linux中都有各自的IPC機制,這裏分別來介紹下。安全

1.1 Linux中的IPC機制種類

Linux中提供了不少進程間通訊機制,主要有管道(pipe)、信號(sinal)、信號量(semophore)、消息隊列(Message)、共享內存(Share Memory)、套接字(Socket)等。架構

管道併發

管道是Linux由Unix那裏繼承過來的進程間的通訊機制,它是Unix早期的一個重要通訊機制。管道的主要思想是,在內存中建立一個共享文件,從而使通訊雙方利用這個共享文件來傳遞信息。這個共享文件比較特殊,它不屬於文件系統而且只存在於內存中。另外還有一點,管道採用的是半雙工通訊方式的,數據只能在一個方向上流動。異步

簡單的模型以下所示。ide

寫給App開發的Binder原理系列

信號函數

信號是軟件層次上對中斷機制的一種模擬,是一種異步通訊方式,進程沒必要經過任何操做來等待信號的到達。信號能夠在用戶空間進程和內核之間直接交互,內核能夠利用信號來通知用戶空間的進程發生了哪些系統事件。信號不適用於信息交換,比較適用於進程中斷控制。性能

信號量

信號量是一個計數器,用來控制多個進程對共享資源的訪問。它常做爲一種鎖機制,防止某進程正在訪問共享資源時,其餘進程也訪問該資源。主要做爲進程間以及同一進程內不一樣線程之間的同步手段。

消息隊列

消息隊列是消息的鏈表,具備特定的格式,存放在內存中並由消息隊列標識符標識,而且容許一個或多個進程向它寫入與讀取消息。信息會複製兩次,所以對於頻繁或者信息量大的通訊不宜使用消息隊列。

共享內存

多個進程能夠直接讀寫的一塊內存空間,是針對其餘通訊機制運行效率較低而設計的。

爲了在多個進程間交換信息,內核專門留出了一塊內存區,能夠由須要訪問的進程將其映射到本身的私有地址空間。進程就能夠直接讀寫這一塊內存而不須要進行數據的拷貝,從而大大的提升效率。

套接字

套接字是更爲基礎的進程間通訊機制,與其餘方式不一樣的是,套接字可用於不一樣機器之間的進程間通訊。

1.2 Android中的IPC機制

Android系統是基於Linux內核的,在Linux內核基礎上,又拓展出了一些IPC機制。Android系統除了支持套接字,還支持序列化、Messenger、AIDL、Bundle、文件共享、ContentProvider、Binder等。Binder會在後面介紹,先來了解前面的IPC機制。

序列化

序列化指的是Serializable/Parcelable,Serializable是Java提供的一個序列化接口,是一個空接口,爲對象提供標準的序列化和反序列化操做。Parcelable接口是Android中的序列化方式,更適合在Android平臺上使用,用起來比較麻煩,效率很高。

Messenger

Messenger在Android應用開發中的使用頻率不高,能夠在不一樣進程中傳遞Message對象,在Message中加入咱們想要傳的數據就能夠在進程間的進行數據傳遞了。Messenger是一種輕量級的IPC方案並對AIDL進行了封裝。

AIDL

AIDL全名爲Android interface definition Language,即Android接口定義語言。Messenger是以串行的方式來處理客戶端發來的信息,若是有大量的消息發到服務端,服務端仍然一個一個的處理再響應客戶端顯然是不合適的。另外還有一點,Messenger用來進程間進行數據傳遞可是卻不能知足跨進程的方法調用,這個時候就須要使用AIDL了。

Bundle

Bundle實現了Parcelable接口,因此它能夠方便的在不一樣的進程間傳輸。Acitivity、Service、Receiver都是在Intent中經過Bundle來進行數據傳遞。

文件共享

兩個進程經過讀寫同一個文件來進行數據共享,共享的文件能夠是文本、XML、JOSN。文件共享適用於對數據同步要求不高的進程間通訊。

ContentProvider

ContentProvider爲存儲和獲取數據了提供統一的接口,它能夠在不一樣的應用程序之間共享數據,自己就是適合進程間通訊的。ContentProvider底層實現也是Binder,可是使用起來比AIDL要容易許多。系統中不少操做都採用了ContentProvider,例如通信錄,音視頻等,這些操做自己就是跨進程進行通訊。

2.Linux和Binder的IPC通訊原理

在講到Linux的進程通訊原理以前,咱們須要先了解Liunx中的幾個概念。

寫給App開發的Binder原理系列

內核空間和用戶空間

當咱們接觸到Liunx時,免不了聽到兩個詞,User space(用戶空間)和 Kernel space(內核空間),那麼它們的含義是什麼呢?

爲了保護用戶進程不能直接操做內核,保證內核的安全,操做系統從邏輯上將虛擬空間劃分爲用戶空間和內核空間。Linux 操做系統將最高的1GB字節供內核使用,稱爲內核空間,較低的3GB 字節供各進程使用,稱爲用戶空間。

內核空間是Linux內核的運行空間,用戶空間是用戶程序的運行空間。爲了安全,它們是隔離的,即便用戶的程序崩潰了,內核也不會受到影響。內核空間的數據是能夠進程間共享的,而用戶空間則不能夠。好比在上圖進程A的用戶空間是不能和進程B的用戶空間共享的。

進程隔離

進程隔離指的是,一個進程不能直接操做或者訪問另外一個進程。也就是進程A不能夠直接訪問進程B的數據。

系統調用

用戶空間須要訪問內核空間,就須要藉助系統調用來實現。系統調用是用戶空間訪問內核空間的惟一方式,保證了全部的資源訪問都是在內核的控制下進行的,避免了用戶程序對系統資源的越權訪問,提高了系統安全性和穩定性。

進程A和進程B的用戶空間能夠經過以下系統函數和內核空間進行交互。

  • copy_from_user:將用戶空間的數據拷貝到內核空間。
  • copy_to_user:將內核空間的數據拷貝到用戶空間。

內存映射

因爲應用程序不能直接操做設備硬件地址,因此操做系統提供了一種機制:內存映射,把設備地址映射到進程虛擬內存區。

舉個例子,若是用戶空間須要讀取磁盤的文件,若是不採用內存映射,那麼就須要在內核空間創建一個頁緩存,頁緩存去拷貝磁盤上的文件,而後用戶空間拷貝頁緩存的文件,這就須要兩次拷貝。

採用內存映射,以下圖所示。

寫給App開發的Binder原理系列

因爲新建了虛擬內存區域,那麼磁盤文件和虛擬內存區域就能夠直接映射,少了一次拷貝。

內存映射全名爲Memory Map,在Linux中經過系統調用函數mmap來實現內存映射。將用戶空間的一塊內存區域映射到內核空間。映射關係創建後,用戶對這塊內存區域的修改能夠直接反應到內核空間,反之亦然。內存映射能減小數據拷貝次數,實現用戶空間和內核空間的高效互動。

2.1 Linux的IPC通訊原理

瞭解Liunx中的幾個概念後,就能夠學習Linux的IPC通訊原理了,以下圖所示。

寫給App開發的Binder原理系列

內核程序在內核空間分配內存並開闢一塊內核緩存區,發送進程經過copy_from_user函數將數據拷貝到到內核空間的緩衝區中。一樣的,接收進程在接收數據時在本身的用戶空間開闢一塊內存緩存區,而後內核程序調用 copy_to_user() 函數將數據從內核緩存區拷貝到接收進程。這樣數據發送進程和數據接收進程完成了一次數據傳輸,也就是一次進程間通訊。

Linux的IPC通訊原理有兩個問題:

  1. 一次數據傳遞須要經歷:用戶空間 --> 內核緩存區 --> 用戶空間,須要2次數據拷貝,這樣效率不高。
  2. 接收數據的緩存區由數據接收進程提供,可是接收進程並不知道須要多大的空間來存放將要傳遞過來的數據,所以只能開闢儘量大的內存空間或者先調用API接收消息頭來獲取消息體的大小,浪費了空間或者時間。

2.2 Binder的通訊原理

Binder是基於開源的OpenBinder實現的,OpenBinder最先並非由Google公司開發的,而是Be Inc公司開發的,接着由Palm, Inc.公司負責開發。後來OpenBinder的做者Dianne Hackborn加入了Google公司,並負責Android平臺的開發工做,順便把這項技術也帶進了Android。

Binder是基於內存映射來實現的,在前面咱們知道內存映射一般是用在有物理介質的文件系統上的,Binder沒有物理介質,它使用內存映射是爲了跨進程傳遞數據。

寫給App開發的Binder原理系列

Binder通訊的步驟以下所示。

1.Binder驅動在內核空間建立一個數據接收緩存區。

2.在內核空間開闢一塊內核緩存區,創建內核緩存區和數據接收緩存區之間的映射關係,以及數據接收緩存區和接收進程用戶空間地址的映射關係。

3.發送方進程經過copy_from_user()函數將數據拷貝 到內核中的內核緩存區,因爲內核緩存區和接收進程的用戶空間存在內存映射,所以也就至關於把數據發送到了接收進程的用戶空間,這樣便完成了一次進程間的通訊。

整個過程只使用了1次拷貝,不會由於不知道數據的大小而浪費空間或者時間,效率更高。

3.爲何要使用Binder

Android是基於Linux內核的 ,Linux提供了不少IPC機制,而Android卻本身設計了Binder來進行通訊,主要是由於如下幾點。

性能方面

性能方面主要影響的因素是拷貝次數,管道、消息隊列、Socket的拷貝次書都是兩次,性能不是很好,共享內存不須要拷貝,性能最好,Binder的拷貝次書爲1次,性能僅次於內存拷貝。

穩定性方面

Binder是基於C/S架構的,這個架構一般採用兩層結構,在技術上已經很成熟了,穩定性是沒有問題的。共享內存沒有分層,難以控制,併發同步訪問臨界資源時,可能還會產生死鎖。從穩定性的角度講,Binder是優於共享內存的。

安全方面

Android是一個開源的系統,而且擁有開放性的平臺,市場上應用來源很廣,所以安全性對於Android 平臺而言極其重要。

傳統的IPC接收方沒法得到對方可靠的進程用戶ID/進程ID(UID/PID),沒法鑑別對方身份。Android 爲每一個安裝好的APP分配了本身的UID,經過進程的UID來鑑別進程身份。另外,Android系統中的Server端會判斷UID/PID是否知足訪問權限,而對外只暴露Client端,增強了系統的安全性。

語言方面

Linux是基於C語言,C語言是面向過程的,Android應用層和Java Framework是基於Java語言,Java語言是面向對象的。Binder自己符合面向對象的思想,所以做爲Android的通訊機制更合適不過。

從這四方面來看,Linux提供的大部分IPC機制根本沒法和Binder相比較,而共享內存只在性能方面優於Binder,其餘方面都劣於Binder,這些就是爲何Android要使用Binder來進行進程間通訊,固然系統中並非全部的進程通訊都是採用了Binder,而是根據場景選擇最合適的,好比Zygote進程與AMS通訊使用的是Socket,Kill Process採用的是信號。

4.爲何要學習Binder?

Binder機制在Android中的地位舉足輕重,咱們須要掌握的不少原理都和Binder有關:

  1. 系統中的各個進程是如何通訊的?
  2. Android系統啓動過程
  3. AMS、PMS的原理
  4. 四大組件的原理,好比Activity是如何啓動的?
  5. 插件化原理
  6. 系統服務的Client端和Server端是如何通訊的?(好比MediaPlayer和MeidaPlayerService)

上面只是列了一小部分,簡單來講說,好比系統在啓動時,SystemServer進程啓動後會建立Binder線程池,目的是經過Binder,使得在SystemServer進程中的服務能夠和其餘進程進行通訊了。再好比咱們常說的AMS、PMS都是基於Binder來實現的,拿PMS來講,PMS運行在SystemServer進程,若是它想要和DefaultContainerService通訊(是用於檢查和複製可移動文件的系統服務),就須要經過Binder,由於DefaultContainerService運行在com.android.defcontainer進程。

還有一個比較常見的C/S架構間通訊的問題,Client端的MediaPlayer和Server端的MeidaPlayerService不是運行在一個進程中的,一樣須要Binder來實現通訊。

能夠說Binder機制是掌握系統底層原理的基石。根據Android系統的分層,Binder機制主要分爲如下幾個部分。

寫給App開發的Binder原理系列

上圖並無給出Binder機制的具體的細節,而是先給出了一個概念,根據系統的Android系統的分層,我將Binder機制分爲了Java Binder、Native Binder、Kernel Binder,實際上Binder的內容很是多,徹底能夠寫一原本介紹,可是對於應用開發來講,並不須要掌握那麼多的知識點。

Android學習PDF+架構視頻+面試文檔+源碼筆記

最後

感謝你們能耐着性子,看完我囉哩囉嗦的文章。

在這裏我也分享一份本身收錄整理的Android學習PDF+架構視頻+面試文檔+源碼筆記,還有高級架構技術進階腦圖、Android開發面試專題資料,高級進階架構資料幫助你們學習提高進階,也節省你們在網上搜索資料的時間來學習,也能夠分享給身邊好友一塊兒學習

若是你有須要的話,能夠點贊關注我,而後加入Android開發交流羣(820198451)免費領取

寫給App開發的Binder原理系列

寫給App開發的Binder原理系列

相關文章
相關標籤/搜索