Binder本地框架
本地Binder框架包含以下類(frameworks/native/libs/binder):
RefBase, IInterface,BnInterface,BpInterface,BpRefBase,Parcel 等等
1) RefBase類(frameworks/native/include/utils/RefBase.h)
引用的基類,android本地代碼裡採用了智能指針,有強指針,也有弱指針。不過不用糾結於這些細節。
2) IInterface(frameworks/native/include/binder/IInterface.h)
自定義的binder service接口必須繼承自IInterface(如ITestService),它的onAsBinder方法為抽象方法,該方法的實現在BpInterface和BnInterface模版類裡。
3) BpRefBase(frameworks/native/include/binder/Binder.h)
客戶端間接用到該類,用於保存IBinder指針,remote()方法即返回IBinder指針。
4) ITestService
聲明的binder service接口,在該接口裡會聲明所有提供的服務方法(使用純虛函數),並用宏DECLARE_META_INTERFACE進行聲明,這樣會添加靜態字段descriptor,靜態方法asInterface,虛方法getInterfaceDescriptor,以及構造函數和析構函數。另外只需要使用IMPLEMENT_META_INTERFACE(INTERFACE, NAME)來即可定義用宏DECLARE_META_INTERFACE聲明的這些方法和字段。
DECLARE_META_INTERFACE宏的源碼如下所示:
1
2
3
4
5
6
7
| #define DECLARE_META_INTERFACE(INTERFACE) \
static const android::String16 descriptor; \
static android::sp<I##INTERFACE> asInterface( \
const android::sp<android::IBinder>& obj); \
virtual const android::String16& getInterfaceDescriptor() const;\
I##INTERFACE(); \
virtual ~I##INTERFACE();
|
若使用DECLARE_META_INTERFACE(TestService); 則會擴展為:
1
2
3
4
5
6
| static const android::String16 descriptor; \
static android::sp<ITestService> asInterface( \
const android::sp<android::IBinder>& obj); \
virtual const android::String16& getInterfaceDescriptor() const; \
ITestService(); \
virtual ~ITestService();
|
宏函數IMPLEMENT_META_INTERFACE(INTERFACE, NAME)的源碼如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const android::String16 I##INTERFACE::descriptor(NAME); \
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const android::sp<android::IBinder>& obj) \
{ \
android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
|
若使用IMPLEMENT_META_INTERFACE(TestService, 「android.TestServer.ITestService」)則會被替換成:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| const android::String16
ITestService::descriptor("android.TestServer.ITestService"); \
const android::String16& \
ITestService::getInterfaceDescriptor() const { \
return ITestService::descriptor; \
} \
android::sp<ITestService> ITestService::asInterface( \
const android::sp<android::IBinder>& obj) \
{ \
android::sp<ITestService> intr; \
if (obj != NULL) { \
intr = static_cast<ITestService*>( \
obj->queryLocalInterface( \
ITestService::descriptor).get()); \
if (intr == NULL) { \
intr = new BpTestService(obj); \
} \
} \
return intr; \
} \
ITestService::ITestService() { } \
ITestService::~ITestService() { } \
|
5) BpInterface(frameworks/native/include/binder/Binder.h)
該類是一個模版類,需和某個繼承自IIterface的類結合使用。
它的聲明如下所示:
1
2
3
4
5
6
7
8
9
| template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
|
因此BpInterface會繼承兩個類,一個父類是繼承自IInterface的類,一個是BpRefbase,我們通常聲明的客戶端代理類會繼承自BpInterface
6) BnInterface(frameworks/native/include/binder/IInterface.h)
該類也是一個模版類,需和某個繼承自IIterface的類結合使用。
它的聲明如下所示:
1
2
3
4
5
6
7
8
9
10
11
| template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface>
queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
virtual IBinder* onAsBinder();
};
|
因此BnInterface也會繼承兩個類,一個父類是繼承自IInterface的binder service接口類,一個是代表Binder service服務端的BBinder類,我們通常聲明的服務端類會直接繼承自BnInterface。
該類實現了IBinder聲明的另外兩個方法,queryLocalInterface和getInterfaceDescriptor。
再介紹一個重要的宏函數interface_cast,它的源碼如下所示:
1
2
3
4
5
| template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
|
若使用interface_cast < ITestService > (binder),會被擴展為:
1
2
3
4
| inline sp< ITestService > interface_cast(const sp<IBinder>& obj)
{
return ITestService::asInterface(obj);
}
|
而ITestService::asInterface方法是ITestService接口聲明時使用DECLARE_META_INTERFACE(TestService)聲明的函數
IServiceManager類圖
從先前的博客《
Binder IPC程序結構》可知,servicemanager其實是init.rc裡聲明的本地服務,由init進程啟動它作為一個單獨的進程運行。不管是提供binder service的服務端還是使用binder service的客戶端,都是在單獨的進程,他們都需要首先獲得servicemananger的IBinder指針,然後利用IBinder指針建立IServiceManager接口對象。通過《
Binder 機制詳解—重要函數調用流程分析》我們已經知道如何獲得servicemananger的IBinder指針,並利用該IBinder指針建立IServiceMananger接口對象。
IServiceManager相關類如下圖所示:(若看不清,請點擊看大圖)
IServiceManager是表示servicemanager的接口,有如下方法:
1) getService獲得binder service引用,
2) checkService獲得binder service引用,
3) addService添加binder service,
4) listServices 列舉所有binder service。
servicemanager的binder service服務端其實是在frameworks/base/cmds/servicemanager 裡實現,BnServiceMananger實際上並未使用。BpServiceMananger就是利用獲得的IBinder指針建立的IServiceMananger對象的實際類型。