接触过android的人都知道Binder服务调用是android系统的基础。它担负是跨进程或进程内调用和数据传递的任务。理解它是理解android众多services的基础。binder服务的层次图如下:
从图中看出,一个binder服务基本分为3层:第一层业务层,它是服务的主体;第二层是粘合层,它把服务的主体和下层的binder层粘合在一起,在这一层上,可以进行transact()调用;第三层是binder层,它负责与binder驱动交互,完成跨进程数据传递。下面从服务端实现说起:
Binder服务的C++实现分析
BnXXXService是由模板类BnInterface生成的,BnInterface扮演粘合剂的角色,它把服务主体接口(IXXXService)和服务载体(BBinder)粘和在一起。它定义在frameworks/base/include/binder/IInterface.h:
- 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();
- };
一个新的服务实体类BnXXXService一般用下面的方式定义:
- class BnXXXService : public BnInterface<IXXXService>
- {
- public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
- };
模板展开后,相当于:
- class BnXXXService : public IXXXService, public BBinder{
- public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
- }
这样BnXXXService同时继承于IXXXService和BBinder。IXXXService是服务的接口,具体的服务函数在BnXXXService中实现。必须重载BnXXXService::onTransact(),在其中对不同的请求code,调用不同的函数。BBinder是服务的载体。当客户端发起服务请求,binder驱动找出相应服务的binder对象,这个binder对象就是BBinder,返回给IPCThreadState,IPCThreadState调用BBinder::transact(),如下面1028行代码所示:
- 891 status_t IPCThreadState::executeCommand(int32_t cmd){
- ...
- 897 switch (cmd) {
- ....
- 970 case BR_TRANSACTION:
- 971 {
- 972 binder_transaction_data tr;
- 973 result = mIn.read(&tr, sizeof(tr));
- ....
- 1026 if (tr.target.ptr) {
- 1027 sp<BBinder> b((BBinder*)tr.cookie);
- 1028 const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
- 1029 if (error < NO_ERROR) reply.setError(error);
- 1030
- 1031 } else {
- ....
- 1034 }
- }
1028行调用BBinder::tranact()。BBinder::tranact()是:
- 96 status_t BBinder::transact(
- 97 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
- 98 {
- 99 data.setDataPosition(0);
- 100
- 101 status_t err = NO_ERROR;
- 102 switch (code) {
- ....
- 106 default:
- 107 err = onTransact(code, data, reply, flags);
- 108 break;
- 109 }
- ....
- 115 return err;
- 116 }
107行调用的onTransact(),其实就是BnXXXService::onTransact()。这样就可以在BnXXXService::onTransact()中通过switch语句完成各种各样的服务。有关类的关系如图:
由此看出:BnXXXService包含两部分:一是IXXXService,服务的主体的接口;另一部分是BBinder,它是服务的载体,它和binder驱动共同工作,保证客户的请求最终是对一个binder对象(BBinder类)的调用。从binder驱动的角度,每一个服务就是一个BBinder类,binder驱动负责找出服务对应的BBinder类。然后把这个BBinder类返回给IPCThreadState,IPCThreadState调用BBinder的transact()。BBinder的transact()又会调用onTransact()。BBinder::onTransact()是虚函数,所以实际实际是调用BnXXXService::onTransact(),这样就可在BnXXXService::onTransact()中完成具体的服务函数的调用。
BnXXXService可以用下面的方法以名字“xxx.xxx.serviceName”向ServiceManager注册:
- defaultServiceManager()->addService(String16("xxx.xxx.serviceName"), new BnXXXService());
Binder客户端C++实现分析
如果说BnInterface是服务端服务主体和载体的粘和剂,那么BpInterface就是客户端代理和binder载体的粘合剂。它的定义:
- template<typename INTERFACE>
- class BpInterface : public INTERFACE, public BpRefBase
- {
- public:
- BpInterface(const sp<IBinder>& remote);
- protected:
- virtual IBinder* onAsBinder();
- };
与服务端类似,客服端一般也用下面的方式得到客户端的服务代理:
- class BpXXXService: public BpInterface<IXXXService>{
- }
- class BpXXXService : public IXXXService, public BpRefBase{
- public:
- BpXXXService(const sp<IBinder& remote);
- ....
- };
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("IXXXService.name"));
- sp<IXXXService> cs = interface_cast<IXXXService>(binder);
如代码所示:先通过defaultServiceManager()得到IServiceManager的客户代理,然后这个IServiceManager对象查询"IXXXService.name"服务,ServiceManager::getService()返回对应服务的IBinder。最后,interface_cast把这个IBinder转换成服务的客户端代理类BpXXXService。interface_cast的定义如下,
- template<typename INTERFACE>
- inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
- {
- return INTERFACE::asInterface(obj);
- }
#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::asInterface( \
const android::sp& obj) \
{ \
android::sp intr; \
if (obj != NULL) { \
intr = static_cast( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
关键在:如果obj是BBinder,obj->queryLocalInterface()返回接口本身;如果是BpBinder,则返回NULL。利用这个特性,当queryLocalInterface()返回NULL时,程序构造一个BpXXXService。这就是interface_cast(const sp& obj)返回的客户端代理类BpXXXService。
这里有个细节,binder驱动实际上返回的是服务的句柄(handle),而getService返回的是IBinder。这中间发生了什么?看看getService(),getSerivice()调用checkService():
- virtual sp<IBinder> checkService( const String16& name) const
- {
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeString16(name);
- remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
- return reply.readStrongBinder();
- }
CHECK_SERVICE_TRANSACTION的结果放在reply,binder驱动返回的服务句柄放在reply中,它应该在Parcel::readStrongBinder()中被转换成sp。看看Parcel::readStrongBinder()
- sp<IBinder> Parcel::readStrongBinder() const
- {
- sp<IBinder> val;
- unflatten_binder(ProcessState::self(), *this, &val);
- return val;
- }
- ...
- status_t unflatten_binder(const sp<ProcessState>& proc,
- const Parcel& in, sp<IBinder>* out)
- {
- const flat_binder_object* flat = in.readObject(false);
-
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_BINDER:
- *out = static_cast<IBinder*>(flat->cookie);
- return finish_unflatten_binder(NULL, *flat, in);
- case BINDER_TYPE_HANDLE:
- *out = proc->getStrongProxyForHandle(flat->handle);
- return finish_unflatten_binder(
- static_cast<BpBinder*>(out->get()), *flat, in);
- }
- }
- return BAD_TYPE;
- }
Parcel::readStrongBinder()调unflatten_binder()。在unflatten_binder()里,由于binder驱动返回的是handle,所以ProcessState::getStrongProxyForHandle()被调用。
- sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
- {
- sp<IBinder> result;
- AutoMutex _l(mLock);
- handle_entry* e = lookupHandleLocked(handle);
- if (e != NULL) {
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- b = new BpBinder(handle); /*以handle为参数构造BpBinder*/ e->binder = b;
- if (b) e->refs = b->getWeakRefs();
- result = b;
- } else {
- ....
- }
- }
- return result;
- }
如果应用是第一次请求服务,那lookupHandleLocked(handle)应该返回Null 。这样ProcessState::getStrongProxyForHandle()构造一个以handle为参数构造BpBinder。这个BpBinder就是getService()得到IBinder。这样这个至关重要的handle被保存在BpBinder里。这个BpBinder也是interface_cast(const sp& obj)中输入参数的IBinder。
客户端涉及的类关系图:
到此为止,我们大致勾画出binder调用的过程,服务端用BnInterface模板,把具体服务的接口和BBinder结合起来生成一个服务类。然后把这个服务类向ServiceManager注册,注册简单地说就是把一个服务的名字和它对应的BBinder的句柄(handle)在ServiceManager中关联起来。以后有人需要这个服务,可以用名字得到它的句柄,用这个句柄,binder驱动就可以找到具体的BBinder服务类了。
客户端用BpInterface模板,把具体服务的接口和BpBinder结合起来生成一个客户端代理类。客户端代理类的实质就是一个服务句柄,这个句柄从binder驱动中返回给应用层,应用层再用Parcel::readStrongBinder()把它转换成sp,并把它保存在BpBinder。