在binder系统中,其主要涉及三个应用程序,以我们之前编写的C++程序为例,分别为test_server,test_client,ServiceManageer。
其中test_client通过代理类BpHelloService与test_server进行通信,在最初阶段,test_server会通过addservice向ServiceManageer添加服务,test_server与ServiceManageer的通信时通过BpServiceManageer。test_client使用getSsrvice获取服务的时候,也是是通过BpServiceManageer进行通信。
BpServiceManageer其中的handle==0,BpHelloService中的handle是通过BpServiceManageer.getService(“hello”)获得。在我们实验中,其为1。在上面提到的两个代理类,.BpServiceManageer与BpHelloService是非常相似的。其他们的各类继承关系如夏图所示: 打开test_server.cpp,与test_client.cpp我们可以在其中找到
/* 获得BpServiceManager */
sp sm = defaultServiceManager();
进入IServiceManager.cpp,我们查看一下defaultServiceManager的实现过程:
获取BpServiceManager过程sp defaultServiceManager()
/*把handle(0)转化为IServiceManager接口(BpServiceManager),*/
gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL));
/*获得一个代理对象,指定其Handle为0*/
getStrongProxyForHandle(0);
/*该处的handle为0,mhandle = handle*/
b = new BpBinder(handle);
下面我们分析
/*把handle(0)转化为IServiceManager接口(BpServiceManager),*/
gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL));
在这里等价为:
interface_cast(new BpBinder(0))
/*等价INTERFACE::asInterface(obj)*/
IServiceManager::asInterface(obj);
/*其中obj为new BpBinder(0)*/
return BpServiceManager(obj)
下面我们看看BpServiceManager的构造函数,打开IServiceManager.cpp文件:
BpServiceManager(const sp& impl): BpInterface(impl)
可以知道BpServiceManager继承于BpServiceManager,其BpInterface构造函数如下:
inline BpInterface::BpInterface(const sp& remote)
: BpRefBase(remote)
{
}
其上BpRefBase如下:
BpRefBase::BpRefBase(const sp& o): mRemote(o.get()), mRefs(NULL), mState(0)
通过上面的分析,我们做一些总结,defaultServiceManager构造了一个BpServiceManager对象,其中他的mRemoto = new BpBinder(0),则mRemoto.handle=0.
下面我能分析获取BpHelloService的过程,
获取BpHelloService的过程,代开test_client.cpp
/*getService在IServiceManager.cpp中实现*/
sp binder =sm->getService(String16("hello"));
sp svc = checkService(name);
//构建数据,name=“hello”
data.writeString16(name);
/*发起数据传输*/
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
/*接收数据时候,取出数据handle然后返回*/
return reply.readStrongBinder();
return unflatten_binder(ProcessState::self(), *this, val);
const flat_binder_object* flat = in.readObject(false);
/*取出handle*/
*out = proc->getStrongProxyForHandle(flat->handle)
b = new BpBinder(handle);
/* service肯定是BpHelloServie指针 */
/*把binder转换为IHelloService接口(BphelloService对象)*/
/*binder是一个Bpbinder对象,里面含有HelloService的handle*/
sp service =interface_cast(binder);
现在我们总结一下获取BpHelloService的过程,调用BpServiceManage的getService的函数,获得一个flat_dinder_object,从中取出handlr,创建一个Bpbinder(handle). 然后通过interface_cast使用Bpbinder创建一个BpHelloService对象。
获取过程异同点下面我们来看看获得BpHelloService与BpServiceManager的不同点,如下: 他们的重点在于handle,构建BpServiceManager其handle为0,BpHelloService的handle来自于getservice()。
BpServiceManager派生于BpRefBase,含有IBinder+mRemote指针。 BpHelloService也派生于BpRefBase,mRemote指向Bpbinder对象,其含有handle。
获得BpServiceManager获得BpHelloService,最终:
sp defaultServiceManager()
/*把handle(0)转化为IServiceManager接口(BpServiceManager),*/
gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL));
现在我们看看另外一个问题: 代理类如何发送数据ioctl,数据中含有handle,以及其他构造参数。我们打开BpHelloService.app:
void sayhello(void)
{
/* 构造/发送数据 */
Parcel data, reply;
data.writeInt32(0);
remote()->transact(HELLO_SVR_CMD_SAYHELLO, data, &reply);
}
首先构造数据,然后调用 remote()->transact发送。其中的remote是在Bpbinder.cpp实现:
status_t BpBinder::transact(
status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);