6.6 學(xué)以致用
全書中可能惟有Binder系統(tǒng)有如此大的魅力,讓我單獨用一節(jié)來介紹如何使用它。
6.6.1 純Native的Service
純Native的Service表示代碼都在Native層。Native層有很多Service,前面的MS不就是一個重量級的嗎?
假設(shè)Service叫Test,我們該如何實現(xiàn)呢?完全可以模仿MS!具體實現(xiàn)過程如代碼所示:
[-->Test.cpp::范例]
- int main()
- {
- sp<ProcessState> proc(ProcessState::self());
- sp<IServiceManager> sm = defaultServiceManager();
- //記住注冊你的服務(wù),否則誰也找不著你!
- sm->addService(“service.name”,new Test());
- //如果壓力不大,可以不用單獨搞一個線程。
- ProcessState::self()->startThreadPool();
- //這個是必須的,否則主線程退出了,你也完了。
- IPCThreadState::self()->joinThreadPool();
- }
Test是怎么定義的呢?我們是跨進程的C/S,所以本地需要一個BnTest,對端需要提供一個代理BpTest。為了不暴露Bp的身份,Bp的定義和實現(xiàn)都放在BnTest.cpp中了。
注意 你雖可以暴露Bp的身份(輸出它的頭文件),但卻沒有必要,因為客戶端用的是基類ITest指針。
1. 我能干什么
ITest接口表明了它所提供的服務(wù),例如getTest和setTest等,這個與業(yè)務(wù)邏輯相關(guān),代碼如下所示:
說明 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系統(tǒng),需要定義BnTest和對客戶端透明的BpTest。BnTest定義既可以與上面的Test定義放在一塊,也可以分開,如下所示:
[-->ITest.h::聲明BnTest]
- class BnTest: public BnInterface<ITest>
- {
- public:
- //由于ITest是個純虛類,而BnTest只實現(xiàn)了
onTransact函數(shù),所以BnTest依然是一個純虛類。- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
- };
另外,我們還要使用IMPLEMENT宏。參考BnMediaPlayerService的方法,把BnTest和BpTest的實現(xiàn)都放在ITest.cpp中,如下所示:
[-->ITest.cpp::BnTest的實現(xiàn)]
- 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();//子承父業(yè),由Test完成。
- return NO_ERROR;
- } break; //SET_XXX類似。
- .......
BpTest也在這里實現(xiàn)吧,如下所示:
[-->ITest.cpp::BpTest的實現(xiàn)]
- 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);
- //打包請求數(shù)據(jù),然后交給BpBinder通信層處理。
- remote()->transact(GET_Test, data, &reply);
- return;
- }
- //setTest類似。
- ......
純Native的Service寫起來量大一些,上面的代碼還只是把C/S的框架寫好了,真正的業(yè)務(wù)處理尚未開始,不過感覺卻很踏實,很厚重。那么,Java層的Service該怎么寫呢?