狐狸毛可以用水洗吗:[z]纯Native的Service

来源:百度文库 编辑:偶看新闻 时间:2024/06/11 11:09:39

6.6.1 纯Native的Service

2011-09-22 10:19 邓凡平 机械工业出版社 我要评论(0) 字号:T | T

综合评级:

想读()   在读()   已读()    品书斋鉴()    已有人发表书评

《深入理解Android:卷I》第6章深入理解Binder,本章拓展思考部分讨论了与Binder有关的三个问题,它们分别是Binder和线程的关系、死亡通知以及匿名Service。笔者希望,通过本章的学习,大家能更深入地认识Binder的本质。本节为大家介绍纯Native的Service。

AD:


    6.6 学以致用

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

    6.6.1 纯Native的Service

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

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

    [-->Test.cpp::范例]

    1. int main()  
    2. {  
    3.    sp proc(ProcessState::self());  
    4.   sp sm = defaultServiceManager();  
    5.   //记住注册你的服务,否则谁也找不着你!  
    6.   sm->addService(“service.name”,new Test());  
    7.   //如果压力不大,可以不用单独搞一个线程。  
    8.   ProcessState::self()->startThreadPool();  
    9.   //这个是必须的,否则主线程退出了,你也完了。  
    10.   IPCThreadState::self()->joinThreadPool();  

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

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

    1. 我能干什么

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

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

    [-->ITest.h::声明ITest]

    1. //需要从IInterface派生  
    2. class ITest: public IInterface。  
    3. {  
    4. public:  
    5.   //神奇的宏 DECLARE_META_INTERFACE。  
    6.   DECLARE_META_INTERFACE(Test);  
    7.   virtual void getTest() = 0;  
    8.   virtual void setTest() = 0;  
    9. }//ITest是一个接口类。 

    2. 定义BnTest和BpTest

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

    [-->ITest.h::声明BnTest]

    1. class BnTest: public BnInterface 
    2. {  
    3. public:  
    4.    //由于ITest是个纯虚类,而BnTest只实现了
      onTransact函数,所以BnTest依然是一个纯虚类。  
    5.     virtual status_t    onTransact( uint32_t code,  
    6.                                     const Parcel& data,  
    7.                                     Parcel* reply,  
    8.                                     uint32_t flags = 0);  
    9.  
    10. }; 

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

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

    1. IMPLEMENT_META_INTERFACE(Test, "android
      .Test.ITest");//IMPLEMENT宏  
    2.  
    3. status_t BnTest::onTransact(  
    4.     uint32_t code, const Parcel& data,
      Parcel* reply, uint32_t flags)  
    5. {  
    6.     switch(code) {  
    7.         case GET_Test: {  
    8.            CHECK_INTERFACE(ITest, data, reply);  
    9.              getTest();//子承父业,由Test完成。  
    10.             return NO_ERROR;  
    11.         } break; //SET_XXX类似。  
    12. ....... 

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

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

    1. class BpTest: public BpInterface 
    2. {  
    3. public:  
    4.     BpXXX (const sp& impl)  
    5.         : BpInterface< ITest >(impl)  
    6.     {  
    7. }  
    8. vitural getTest()  
    9. {  
    10. Parcel data, reply;  
    11.    data.writeInterfaceToken(ITest::getInterfaceDescriptor());  
    12.    data.writeInt32(pid);  
    13.    //打包请求数据,然后交给BpBinder通信层处理。  
    14.    remote()->transact(GET_Test, data, &reply);  
    15.    return;  
    16. }  
    17. //setTest类似。  
    18. ...... 

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