Android Binder 跨程序通訊
阿新 • • 發佈:2018-12-18
1.基本前提知識:
1.1 程序隔離
1.LINUX 中 每個程序有自己的虛擬記憶體空間,作業系統將這種虛擬記憶體空間對映到實體記憶體空間 ,每個程序不能操作其他程序的記憶體空間;
2.只有作業系統才有許可權操作實體記憶體空間;
3. 1 和 2 保證了程序的記憶體安全;
1.2 使用者空間和核心空間
- 使用者空間:表示程序執行在一個特定的操作模式中,沒有接觸實體記憶體或裝置的許可權
- 核心空間:表示獨立於普通的應用程式,可以訪問受保護的記憶體空間,也有訪問底層硬體裝置的所有許可權
- (2位作業系統而言,它的定址空間(虛擬儲存空間)為4G ,了保證使用者程序不能直接操作核心,保證核心的安全,操心繫統將虛擬空間劃分為兩部分,一部分為核心空間,一部分為使用者空間。針對linux作業系統而言,將最高的1G位元組,供核心使用,稱為核心空間,而將較低的3G位元組,供各個程序使用,稱為使用者空間)
1.3 核心模組/驅動
- 通過系統呼叫,使用者空間可以訪問核心空間 :Linux的動態可載入核心模組機制解決了這個問題,模組是具有獨立功能的程式,它可以被單獨編譯,但不能獨立執行;
- Android系統可以通過新增一個核心
- 傳統的程序:通訊方式對於通訊雙方的身份並沒有做出嚴格的驗證,只有在上層協議上進行架設
- 模組執行在核心空間,使用者程序之間的通過這個模組作為橋樑,就可以完成通訊了
- 在Android系統中,這個執行在核心空間的,負責各個使用者程序通過Binder通訊的核心模組叫做Binder驅動
- (使用者空間:使用者程序A <---> 核心空間:Binder驅動 <--->
- Linux的虛擬記憶體機制導致記憶體的隔離,進而導致程序隔離
- 程序隔離的出現導致對記憶體的操作被劃分為使用者空間和核心空間
- 使用者空間需要跨許可權去訪問核心空間,必須使用系統呼叫去實現
- 系統呼叫需要藉助核心模組/驅動去完成
2.Binder 的優勢:
LINUX 中有:管道、訊息佇列、訊號量、記憶體共享、套接字等跨程序方式 ;
2.1 傳輸效能好
- Socket:是一個通用介面,導致其傳輸效率低,開銷大
- 共享記憶體:雖然在傳輸時不需要拷貝資料,但其控制機制複雜
- Binder:複雜資料型別傳遞可以複用記憶體,需要拷貝1次資料
- 管道和訊息佇列:採用儲存轉發方式,至少需要拷貝2次資料,效率低
2.2 安全性好
- 傳統的程序:通訊方式對於通訊雙方的身份並沒有做出嚴格的驗證,只有在上層協議上進行架設
- Binder機制:從協議本身就支援對通訊雙方做身份校檢,因而大大提升了安全性
3.Binder 通訊原理
- Service端通過Binder驅動在ServiceManager的查詢表中註冊Object物件的add方法
- Client端通過Binder驅動在ServiceManager的查詢表中找到Object物件的add方法,並返回proxy物件的add方法,add方法是個空實現,proxy物件也不是真正的Object物件,是通過Binder驅動封裝好的代理類的add方法
- 當Client端呼叫add方法時,Client端會呼叫proxy物件的add方法,通過Binder驅動去請求ServiceManager來找到Service端真正物件,然後呼叫Service端的add方法