Android世界的粘合劑——Binder
Android是個多程序的作業系統,程序包括系統服務和應用程式程序,程序與程序之間並不是孤立的,而是可以通過Binder機制相互通訊的,可以說Binder是Android系統程序間的粘合劑,將各個獨立的程序粘合起來形成一個統一的整體。
為什麼要使多程序服務的模式
首先,可以降低第三方應用程式的包大小,系統中有很多服務,比如視窗管理、通知欄管理、通訊錄管理等,如果將系統的服務以SDK的形式提供給APP,那麼APP的包將會很臃腫,系統中的應用將會存在很多相同的程式碼。因此通過C/S架構的多執行緒模式,可以將服務實現成一個服務程序,接收客戶程序的請求,返回結果,因此客戶程序便被輕量化了。同時,這樣也提供訪問許可權的控制,比如並不是每個程序都能訪問使用者的通訊錄,通訊錄服務程序可以統一管理。
Binder世界的成員
Binder世界的成員有:
·Client:客戶端程序,可以是應用程式,也可以是Server
·Server:服務端程序
·ServiceManager:服務管理程序
·binder裝置:Linux裝置
需要注意的是,Client、Server、ServiceManager之間的通訊,都是經過binder裝置進行的。Client、Server、ServiceManager運行於使用者空間,binder裝置驅動運行於核心空間。
Client程序
常見的情況是,Client程序(比如應用程式)需要與系統的某個Service互動,這個Service一定駐留在某個Server程序中,為了與Server通訊,Client程序需要先獲得Server程序的資訊。那麼它首先需要從ServiceManager程序中查詢Server程序,獲得Server程序的地址,才能建立Client與Server的通訊通路。
舉個例子,比如Client程序想要與MediaPlayerService服務通訊,首先通過函式defaultServiceManager()
來獲得IServiceManager
物件,然後通過IServiceManager
的getService(String16("media.player"))
方法拿到對應服務的binder(實際上是BpBinder
物件),然後通過interface_cast<IMediaPlayerService>(binder)
的方式將這個binder包裝到IMediaPlayerService
物件中,從而打通了業務和底層的通訊。
Server程序
Android系統提供許多服務,比如ActivityManagerService、WindowManagerService、MediaPlayerService等,多個服務可能駐留在同一個程序中,比如MediaServer程序就駐留著以下幾個服務:
·AudioFlinger :音訊系統中的重要核心服務。
·AudioPolicyService :音訊系統中關於音訊策略的重要服務。
·MediaPlayerService :多媒體系統中的重要服務。
·CameraService :有關攝像/照相的重要服務。
Server啟動的時候,需要使用Binder機制,與ServiceManager程序通訊,將各個Service加入到ServiceManager程序中,然後啟動執行緒,不斷與binder驅動交流,來監聽客戶端的請求。
ServiceManager程序
ServiceManager是Binder世界裡最特殊的程序,它的地址是0,ServiceManager程序啟動的時候,首先獲取binder裝置,然後告訴binder裝置,自己是ServiceManager程序(呼叫ioctl函式,將自己的地址設定為0),然後啟動迴圈,不斷與binder裝置交流,監聽客戶端的請求,這裡的請求比如:
- Service請求將自己加入到ServiceManager
- Client根據Service的名字查詢某個Service的地址
- 列出系統所有的Service
binder裝置
linux裝置,它是android在核心中專門用於完成程序間通訊而設定的一個虛擬裝置,有自己的驅動程式,其驅動是運行於核心空間的程序,負責程序間binder通訊的建立、binder在程序間的傳遞、binder的引用計數、資料包在程序間的傳遞等一系列底層支援,它與應用程序之間定義了一套介面協議。可以通過open()函式來開啟該裝置,
int fd =open("/dev/binder", O_RDWR);
系統中的程序可以通過ioctl系統呼叫向它傳輸資料,Client、Server、ServiceManager之間的通訊,都需要由binder裝置中轉,無法自行通訊。