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该怎么写呢?