Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server和Client獲得Service Manager接口之路
在前面一篇文章淺談Service Manager成為Android進(jìn)程間通信(IPC)機(jī)制Binder守護(hù)進(jìn)程之路中,介紹了Service Manager是如何成為Binder機(jī)制的守護(hù)進(jìn)程的。既然作為守護(hù)進(jìn)程,Service Manager的職責(zé)當(dāng)然就是為Server和Client服務(wù)了。那么,Server和Client如何獲得Service Manager接口,進(jìn)而享受它提供的服務(wù)呢?本文將簡(jiǎn)要分析Server和Client獲得Service Manager的過(guò)程。
在閱讀本文之前,希望讀者先閱讀Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文提到的參考資料Android深入淺出之Binder機(jī)制,這樣可以加深對(duì)本文的理解。
我們知道,Service Manager在Binder機(jī)制中既充當(dāng)守護(hù)進(jìn)程的角色,同時(shí)它也充當(dāng)著Server角色,然而它又與一般的Server不一樣。對(duì)于普通的Server來(lái)說(shuō),Client如果想要獲得Server的遠(yuǎn)程接口,那么必須通過(guò)Service Manager遠(yuǎn)程接口提供的getService接口來(lái)獲得,這本身就是一個(gè)使用Binder機(jī)制來(lái)進(jìn)行進(jìn)程間通信的過(guò)程。而對(duì)于Service Manager這個(gè)Server來(lái)說(shuō),Client如果想要獲得Service Manager遠(yuǎn)程接口,卻不必通過(guò)進(jìn)程間通信機(jī)制來(lái)獲得,因?yàn)镾ervice Manager遠(yuǎn)程接口是一個(gè)特殊的Binder引用,它的引用句柄一定是0。
獲取Service Manager遠(yuǎn)程接口的函數(shù)是defaultServiceManager,這個(gè)函數(shù)聲明在frameworks/base/include/binder/IServiceManager.h文件中:
sp<IServiceManager> defaultServiceManager();
實(shí)現(xiàn)在frameworks/base/libs/binder/IServiceManager.cpp文件中:
sp<IServiceManager> defaultServiceManager() { if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); } } return gDefaultServiceManager; }
gDefaultServiceManagerLock和gDefaultServiceManager是全局變量,定義在frameworks/base/libs/binder/Static.cpp文件中:
Mutex gDefaultServiceManagerLock; sp<IServiceManager> gDefaultServiceManager;
從這個(gè)函數(shù)可以看出,gDefaultServiceManager是單例模式,調(diào)用defaultServiceManager函數(shù)時(shí),如果gDefaultServiceManager已經(jīng)創(chuàng)建,則直接返回,否則通過(guò)interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))來(lái)創(chuàng)建一個(gè),并保存在gDefaultServiceManager全局變量中。
在繼續(xù)介紹interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))的實(shí)現(xiàn)之前,先來(lái)看一個(gè)類圖,這能夠幫助我們了解Service Manager遠(yuǎn)程接口的創(chuàng)建過(guò)程。
參考資料Android深入淺出之Binder機(jī)制一文的讀者,應(yīng)該會(huì)比較容易理解這個(gè)圖。這個(gè)圖表明了,BpServiceManager類繼承了BpInterface<IServiceManager>類,BpInterface是一個(gè)模板類,它定義在frameworks/base/include/binder/IInterface.h文件中:
template<typename INTERFACE> class BpInterface : public INTERFACE, public BpRefBase { public: BpInterface(const sp<IBinder>& remote); protected: virtual IBinder* onAsBinder(); };
IServiceManager類繼承了IInterface類,而IInterface類和BpRefBase類又分別繼承了RefBase類。在BpRefBase類中,有一個(gè)成員變量mRemote,它的類型是IBinder*,實(shí)現(xiàn)類為BpBinder,它表示一個(gè)Binder引用,引用句柄值保存在BpBinder類的mHandle成員變量中。BpBinder類通過(guò)IPCThreadState類來(lái)和Binder驅(qū)動(dòng)程序并互,而IPCThreadState又通過(guò)它的成員變量mProcess來(lái)打開(kāi)/dev/binder設(shè)備文件,mProcess成員變量的類型為ProcessState。ProcessState類打開(kāi)設(shè)備/dev/binder之后,將打開(kāi)文件描述符保存在mDriverFD成員變量中,以供后續(xù)使用。
理解了這些概念之后,就可以繼續(xù)分析創(chuàng)建Service Manager遠(yuǎn)程接口的過(guò)程了,最終目的是要?jiǎng)?chuàng)建一個(gè)BpServiceManager實(shí)例,并且返回它的IServiceManager接口。創(chuàng)建Service Manager遠(yuǎn)程接口主要是下面語(yǔ)句:
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
看起來(lái)簡(jiǎn)短,卻暗藏玄機(jī),具體可閱讀Android深入淺出之Binder機(jī)制這篇參考資料,這里作簡(jiǎn)要描述。
首先是調(diào)用ProcessState::self函數(shù),self函數(shù)是ProcessState的靜態(tài)成員函數(shù),它的作用是返回一個(gè)全局唯一的ProcessState實(shí)例變量,就是單例模式了,這個(gè)變量名為gProcess。如果gProcess尚未創(chuàng)建,就會(huì)執(zhí)行創(chuàng)建操作,在ProcessState的構(gòu)造函數(shù)中,會(huì)通過(guò)open文件操作函數(shù)打開(kāi)設(shè)備文件/dev/binder,并且返回來(lái)的設(shè)備文件描述符保存在成員變量mDriverFD中。
接著調(diào)用gProcess->getContextObject函數(shù)來(lái)獲得一個(gè)句柄值為0的Binder引用,即BpBinder了,于是創(chuàng)建Service Manager遠(yuǎn)程接口的語(yǔ)句可以簡(jiǎn)化為:
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
再來(lái)看函數(shù)interface_cast<IServiceManager>的實(shí)現(xiàn),它是一個(gè)模板函數(shù),定義在framework/base/include/binder/IInterface.h文件中:
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }
這里的INTERFACE是IServiceManager,于是調(diào)用了IServiceManager::asInterface函數(shù)。IServiceManager::asInterface是通過(guò)DECLARE_META_INTERFACE(ServiceManager)宏在IServiceManager類中聲明的,它位于framework/base/include/binder/IServiceManager.h文件中:
DECLARE_META_INTERFACE(ServiceManager);
展開(kāi)即為:
#define DECLARE_META_INTERFACE(ServiceManager) \ static const android::String16 descriptor; \ static android::sp<IServiceManager> asInterface( \ const android::sp<android::IBinder>& obj); \ virtual const android::String16& getInterfaceDescriptor() const; \ IServiceManager(); \ virtual ~IServiceManager();
IServiceManager::asInterface的實(shí)現(xiàn)是通過(guò)IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")宏定義的,它位于framework/base/libs/binder/IServiceManager.cpp文件中:
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
展開(kāi)即為:
#define IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager") \ const android::String16 IServiceManager::descriptor("android.os.IServiceManager"); \ const android::String16& \ IServiceManager::getInterfaceDescriptor() const { \ return IServiceManager::descriptor; \ } \ android::sp<IServiceManager> IServiceManager::asInterface( \ const android::sp<android::IBinder>& obj) \ { \ android::sp<IServiceManager> intr; \ if (obj != NULL) { \ intr = static_cast<IServiceManager*>( \ obj->queryLocalInterface( \ IServiceManager::descriptor).get()); \ if (intr == NULL) { \ intr = new BpServiceManager(obj); \ } \ } \ return intr; \ } \ IServiceManager::IServiceManager() { } \ IServiceManager::~IServiceManager() { }
估計(jì)寫(xiě)這段代碼的員工是從Microsoft跳槽到Google的。這里我們關(guān)注IServiceManager::asInterface的實(shí)現(xiàn):
android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj) { android::sp<IServiceManager> intr; if (obj != NULL) { intr = static_cast<IServiceManager*>( obj->queryLocalInterface(IServiceManager::descriptor).get()); if (intr == NULL) { intr = new BpServiceManager(obj); } } return intr; }
這里傳進(jìn)來(lái)的參數(shù)obj就則剛才創(chuàng)建的new BpBinder(0)了,BpBinder類中的成員函數(shù)queryLocalInterface繼承自基類IBinder,IBinder::queryLocalInterface函數(shù)位于framework/base/libs/binder/Binder.cpp文件中:
sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor) { return NULL; }
由此可見(jiàn),在IServiceManager::asInterface函數(shù)中,最終會(huì)調(diào)用下面語(yǔ)句:
intr = new BpServiceManager(obj);
即為:
intr = new BpServiceManager(new BpBinder(0));
回到defaultServiceManager函數(shù)中,最終結(jié)果為:
gDefaultServiceManager = new BpServiceManager(new BpBinder(0));
這樣,Service Manager遠(yuǎn)程接口就創(chuàng)建完成了,它本質(zhì)上是一個(gè)BpServiceManager,包含了一個(gè)句柄值為0的Binder引用。
在Android系統(tǒng)的Binder機(jī)制中,Server和Client拿到這個(gè)Service Manager遠(yuǎn)程接口之后怎么用呢?
對(duì)Server來(lái)說(shuō),就是調(diào)用IServiceManager::addService這個(gè)接口來(lái)和Binder驅(qū)動(dòng)程序交互了,即調(diào)用BpServiceManager::addService 。而B(niǎo)pServiceManager::addService又會(huì)調(diào)用通過(guò)其基類BpRefBase的成員函數(shù)remote獲得原先創(chuàng)建的BpBinder實(shí)例,接著調(diào)用BpBinder::transact成員函數(shù)。在BpBinder::transact函數(shù)中,又會(huì)調(diào)用IPCThreadState::transact成員函數(shù),這里就是最終與Binder驅(qū)動(dòng)程序交互的地方了?;貞浺幌虑懊娴念悎D,IPCThreadState有一個(gè)PorcessState類型的成中變量mProcess,而mProcess有一個(gè)成員變量mDriverFD,它是設(shè)備文件/dev/binder的打開(kāi)文件描述符,因此,IPCThreadState就相當(dāng)于間接在擁有了設(shè)備文件/dev/binder的打開(kāi)文件描述符,于是,便可以與Binder驅(qū)動(dòng)程序交互了。
對(duì)Client來(lái)說(shuō),就是調(diào)用IServiceManager::getService這個(gè)接口來(lái)和Binder驅(qū)動(dòng)程序交互了。具體過(guò)程上述Server使用Service Manager的方法是一樣的,這里就不再累述了。
IServiceManager::addService和IServiceManager::getService這兩個(gè)函數(shù)的具體實(shí)現(xiàn),在下面兩篇文章中,會(huì)深入到Binder驅(qū)動(dòng)程序這一層,進(jìn)行詳細(xì)的源代碼分析,以便更好地理解Binder進(jìn)程間通信機(jī)制,敬請(qǐng)關(guān)注。
以上就是對(duì)Android Binder 通信資料的整理,后續(xù)繼續(xù)補(bǔ)充相關(guān)資料,謝謝大家對(duì)本站的支持!
- Android 圖文詳解Binder進(jìn)程通信底層原理
- Android通過(guò)繼承Binder類實(shí)現(xiàn)多進(jìn)程通信
- Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼分析
- Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Client獲得Server遠(yuǎn)程接口過(guò)程源代碼分析
- Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過(guò)程源代碼分析
- Android Binder 通信原理圖文詳解
相關(guān)文章
Android網(wǎng)絡(luò)通信的實(shí)現(xiàn)方式
這篇文章主要為大家詳細(xì)介紹了Android網(wǎng)絡(luò)通信的實(shí)現(xiàn)方式,四種實(shí)現(xiàn)網(wǎng)絡(luò)通信的方式供大家學(xué)習(xí),感興趣的小伙伴們可以參考一下2016-06-06Flutter使用Overlay與ColorFiltered新手引導(dǎo)實(shí)現(xiàn)示例
這篇文章主要介紹了Flutter使用Overlay與ColorFiltered新手引導(dǎo)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Android RecyclerView網(wǎng)格布局示例解析
這篇文章主要介紹了Android RecyclerView網(wǎng)格布局示例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12Android GridView不改變背景色實(shí)現(xiàn)網(wǎng)格線效果
這篇文章主要介紹了Android GridView不改變背景色實(shí)現(xiàn)網(wǎng)格線效果,需要的朋友可以參考下2016-03-03Android實(shí)現(xiàn)Bitmap位圖旋轉(zhuǎn)效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)Bitmap位圖旋轉(zhuǎn)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04android跑馬燈出現(xiàn)重復(fù)跳動(dòng)以及不滾動(dòng)問(wèn)題的解決方法
這篇文章主要介紹了android跑馬燈出現(xiàn)重復(fù)跳動(dòng)以及不滾動(dòng)問(wèn)題的解決方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Android應(yīng)用中通過(guò)Layout_weight屬性用ListView實(shí)現(xiàn)表格
這篇文章主要介紹了Android應(yīng)用中通過(guò)Layout_weight屬性用ListView實(shí)現(xiàn)表格的方法,文中對(duì)Layout_weight屬性先有一個(gè)較為詳細(xì)的解釋,需要的朋友可以參考下2016-04-04Android自定義GestureDetector實(shí)現(xiàn)手勢(shì)ImageView
這篇文章主要為大家詳細(xì)介紹了Android自定義GestureDetector實(shí)現(xiàn)手勢(shì)ImageView的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Android手勢(shì)密碼view學(xué)習(xí)筆記(二)
這篇文章主要為大家詳細(xì)介紹了Android手勢(shì)密碼view的第二篇學(xué)習(xí)筆記,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03