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框架,供参考: