BpXXX、BnXXX同时实现一个接口IXXX。BpXXX主要是用来处理java层传下来的服务请求,然后通过transact将处理请求传给BnXXX(通过binder)。BpINTERFACE是client端的代理接口,BnINTERFACE是server端的代理接口。
首先,定义IXXX接口:
class ITestDaemon : public IInterface, public IBinder::DeathRecipient {
virtual void init();
virtual void testFunc();
}
BpBinder(Binder Proxy):主要功能是负责client向Bn发送调用请求的数据。它是client端binder通信的核心对象,通过调用transact函数,client就可以向Bn发送调用请求和数据。
class BpTestDaemon : public BpInterface<ITestDaemon> {
void init() {
Parcel data, reply;
data.writeInterfaceToken(descr iptor);
remote()->transact(init, data, &reply);
}
void testFunc() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(testFunc, data, &reply);
}
}
BnBinder(Binder Native):BnBinder就是具体干事情的对象。
.H声明
class BnTestDaemon: public BnInterface<ITestDaemon> {
public:
virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
//由于IXXX是个纯虚类,而BnXXX只实现了onTransact函数,所以BnXXX依然是一个纯虚类
};
.cpp实现:
status_t BnTestDaemon::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
switch (code) {
case init: {
CHECK_INTERFACE(ITestDaemon, data, reply);
init(); //调用虚函数
return NO_RROR;
}
case testFunc: {
CHECK_INTERFACE(ITestDaemon, data, reply);
testFunc(); //调用虚函数
return NO_ERROR;
}
}
写Service,实现接口的虚函数
.H
class TestDaemonProxy : public BnTestDaemon {
public:
static TestDaemonProxy* getInstance() {
if (sInstance == NULL) {
sInstance = new TestDaemonProxy();
}
return sInstance;
}
// These reflect binder methods.
virtual void init();
virtual void testFunc();
};
.cpp:
void TestDaemonProxy::init() {
.... //具体实现
}
void TestDaemonProxy::testFunc() {
.... //具体实现
}
主函数中,获得ServiceManager,添加Service。
int main()
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
sm->addService(“service.name”,new TestDaemonProxy());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
binder通信是一种client-server的通信结构
1.从表面上来看,是client通过获得一个server的代理接口,对server进行直接调用;
2.实际上,代理接口中定义的方法与server中定义的方法是一一对应的;
3.client调用某个代理接口中的方法时,代理接口的方法会将client传递的参数打包成为Parcel对象;
4.代理接口将该Parcel发送给内核中的binder driver.
5.server会读取binder driver中的请求数据,如果是发送给自己的,解包Parcel对象,处理并将结果返回;
6.整个的调用过程是一个同步过程,在server处理的时候,client会block住。
系统AudioFlinger服务的Binder框架,供参考: