6.6 学以致用

全书中可能惟有Binder系统有如此大的魅力,让我单独用一节来介绍如何使用它。

6.6.1 纯Native的Service

纯Native的Service表示代码都在Native层。Native层有很多Service,前面的MS不就是一个重量级的吗?

假设Service叫Test,我们该如何实现呢?完全可以模仿MS!具体实现过程如代码所示:


[—>Test.cpp:范例]

int main()

{

sp<ProcessState>proc(ProcessState:self());

sp<IServiceManager>sm=defaultServiceManager();

//记住注册你的服务,否则谁也找不着你!

sm->addService(“service.name”,new Test());

//如果压力不大,可以不用单独搞一个线程。

ProcessState:self()->startThreadPool();

//这个是必须的,否则主线程退出了,你也完了。

IPCThreadState:self()->joinThreadPool();

}


Test是怎么定义的呢?我们是跨进程的C/S,所以本地需要一个BnTest,对端需要提供一个代理BpTest。为了不暴露Bp的身份,Bp的定义和实现都放在BnTest.cpp中了。

注意 你虽可以暴露Bp的身份(输出它的头文件),但却没有必要,因为客户端用的是基类ITest指针。

1.我能干什么

ITest接口表明了它所提供的服务,例如getTest和setTest等,这个与业务逻辑相关,代码如下所示:


说明 getTest也可以返回一个ITestService类型的Service!

[—>ITest.h:声明ITest]

//需要从IInterface派生

class ITest:public IInterface。

{

public:

//神奇的宏DECLARE_META_INTERFACE。

DECLARE_META_INTERFACE(Test);

virtual void getTest()=0;

virtual void setTest()=0;

}//ITest是一个接口类。


2.定义BnTest和BpTest

为了把ITest融入到Binder系统,需要定义BnTest和对客户端透明的BpTest。BnTest定义既可以与上面的Test定义放在一块,也可以分开,如下所示:


[—>ITest.h:声明BnTest]

class BnTest:public BnInterface<ITest>

{

public:

//由于ITest是个纯虚类,而BnTest只实现了onTransact函数,所以BnTest依然是一个纯虚类。

virtual status_t onTransact(uint32_t code,

const Parcel&data,

Parcel*reply,

uint32_t flags=0);

};


另外,我们还要使用IMPLEMENT宏。参考BnMediaPlayerService的方法,把BnTest和BpTest的实现都放在ITest.cpp中,如下所示:


[—>ITest.cpp:BnTest的实现]

IMPLEMENT_META_INTERFACE(Test,"android.Test.ITest");//IMPLEMENT宏

status_t BnTest:onTransact(

uint32_t code,const Parcel&data,Parcel*reply,uint32_t flags)

{

switch(code){

case GET_Test:{

CHECK_INTERFACE(ITest,data,reply);

getTest();//子承父业,由Test完成。

return NO_ERROR;

}break;//SET_XXX类似。

……


BpTest也在这里实现吧,如下所示:


[—>ITest.cpp:BpTest的实现]

class BpTest:public BpInterface<ITest>

{

public:

BpXXX(const sp<IBinder>&impl)

:BpInterface<ITest>(impl)

{

}

vitural getTest()

{

Parcel data,reply;

data.writeInterfaceToken(ITest:getInterfaceDescriptor());

data.writeInt32(pid);

//打包请求数据,然后交给BpBinder通信层处理。

remote()->transact(GET_Test,data,&reply);

return;

}

//setTest类似。

……


纯Native的Service写起来量大一些,上面的代码还只是把C/S的框架写好了,真正的业务处理尚未开始,不过感觉却很踏实,很厚重。那么,Java层的Service该怎么写呢?