天天看點

Android源碼分析之了解Binder通信機制

IPC,即Inner-Process-communication,程序間通信,是Android系統中比較難以了解的一個概念。而Binder則是Android系統中特有的進行IPC的一種方式,相對于Linux自帶的其他方式(如管道)、socket、檔案等而言,Binder具有更大的效率和安全優勢。而本文将從各個層面深入探究Binder的原理。

一、Linux基礎

本文首先 介紹部分和Android的程序間通信有關的Linux基礎知識。

1.程序隔離/虛拟位址空間:Linux系統為了避免程序之間互相幹擾,給各個程序配置設定了一塊虛拟的位址空間,各個程序分别運作在各自的虛拟位址空間内。

2.系統調用:Linux提供的一種調用機制,通過系統調用,使用者控件可以通路核心的應用程式。

二、何為Binder

1.廣義來講,Binder可以了解為Android的一種跨程序通信方式。

2.從Android源碼來看,Binder是一個Java類,實作了IBinder接口。

3.從Android的FrameWork來看,Binder可以看做是ServiceManager連接配接各種系統自帶的Manager(如ActivityManager、WindowManager)和對應的Service(ActivityManagerService,WindowManagerService)的橋梁。

4.從應用層面來講,Binder是用戶端和服務端通信的媒介。當用戶端對服務端進行綁定時,服務端會傳回一個包含了服務端業務調用的Binder類對象,用戶端可以通過此對象調用服務端的方法和資料。

讀到此處,相信大家還是很難對Binder的應用場景,實作方式和作用有很直覺的了解,以下筆者将通過client調用Service的詳細過程對其進行解析。

三、詳解IPC

Android源碼分析之了解Binder通信機制

1、我們将主要圍繞上圖進行分析。

1)圖中有四個關鍵的對象:Server、Client、SeviceManager(圖中最下方的矩形)、Binder驅動。其中前三者運作在客戶空間,而Binder驅動運作在核心空間。Server、Client由應用程式負責提供,而Binder驅動和SeviceManager由系統提供。

2)Binder程序間通信實在OpenBinder的基礎上實作的,其中提供服務的程序分為服務程序,而通路服務的程序分為Client程序,兩者分别運作在不同的程序中。而Server程序和Client程序需要通信,需要借助運作在核心空間的Binder驅動,Binder驅動對使用者空間暴露了一個裝置檔案、dev/binder,應用程式可以依靠他來建立通信通道。

3)當Server空間中的Service啟動時(不一定是Service子類,但需要繼承IInterface接口),會在ServiceManager(下稱SM)中去進行注冊。SM可以看做是Binder程序通信間的上下文管理者,他也需要與Server和Client通信,可以看做是特殊的Service元件。

4)當Client需要調用Service(再次強調,這裡指的Service指的是繼承了IInterface的一個實作類,通常還有一個中間接口IService)中的方法或者資料時,需要根據類名在SM中進行查找,SM會傳回服務端的代理對象,代理對象(Proxy)實作了Service所對應的接口(假設命名為IService,繼承關系為:Service>IService>IInterface)的子類Stub,并對IService中定義的方法做了封裝,使其可以實作程序間讀寫資料(需要需要序列化),是以代理對象可以将資料交由IService的最終實作類進行處理,完成之後再傳回給Client。

上面就是Binder程序間通信機制的大緻流程。下面将在分别對SM,Service元件啟動和其代理對象具體擷取過程作詳細介紹。

5)SM:SM由系統負責啟動,啟動過程分為三個步驟:打開裝置檔案dev/binder将其映射到本程序的位址空間;将自己注冊為Binder程序間通信的額上下文管理者;調用函數binder_loop來循環等待和處理Client的通信請求。SM中含有四個方法getService、checkService、addService、listService,Client通過getService擷取Service的代理對象,Service通過addService将自己注冊進SM中。SM運作在自己的獨立空間,也繼承了IInterface,是以它自身和Server及Client通信也需要跨程序:當Client需要通過SM的getService方法擷取Service代理對象或者Service需要通過addService進行注冊時時,也需要先擷取SM的代理對象,但是不同的是其代理對象擷取比較簡單,Android系統在Binder庫中提供了一個函數defaultServiceManager,通過此方法即可擷取到。

6)Service啟動過程:Service元件是在Server程序中運作的,Server程序啟動時,首先将它裡面的Service元件注冊到SM中,接着再啟動一個Binder線程池來等待和處理Client程序的通信請求。

7)Service代理對象擷取:參考下面AIDL的解析。

四、IPC具體實作:AIDL