Binder机制编程

前面的几篇文章具体介绍了android中binder机制的方方面面,相信你对binder机制已经有了较深刻的理解。俗话说得好“学以致用”,以下我们就通过在android系统中创建一个我们自己的binder服务,来加深对binder机制的理解。

(1)增加新建的服务名称

在service_manager.c文件里有一个结构数组allowed,在allowed结构体数组中增加新建的服务名称

  1. static struct {
  1.     unsigned uid;
  1.     const char *name;
  1. } allowed[] = {
  1. #ifdef LVMX
  1.     { AID_MEDIA, "com.lifevibes.mx.ipc" },
  1. #endif
  1.     { AID_MEDIA, "media.audio_flinger" },
  1.     { AID_MEDIA, "media.player" },
  1.     { AID_MEDIA, "media.camera" },
  1.     { AID_MEDIA, "media.audio_policy" },
  1.     { AID_RADIO, "radio.phone" },
  1.     { AID_RADIO, "radio.sms" },
  1.     { AID_RADIO, "radio.phonesubinfo" },
  1.     { AID_RADIO, "radio.simphonebook" },
  1. /* TODO: remove after phone services are updated: */
  1.     { AID_RADIO, "phone" },
  1.     { AID_RADIO, "isms" },
  1.     { AID_RADIO, "iphonesubinfo" },
  1. { AID_RADIO, "simphonebook" },
  1.  
  1. {AID_NEW, "newservice"}
  1. };
  1.  

(2)定义ImyService类

定义一个继承自IInterface的接口类,须是以大写字母I開始,以IMyService为例接口函数必须为纯虚函数,以便在子类中生产,在定义接口时将DECLARE_META_INTERFACE宏放进接口类定义中,这个宏的最重要作用是将代理对象BpBinder转化成本地封装的服务代理对象(在这里是BpMyService对象),代码大致例如以下:

  1. Class ImyService:public IInterface
  1. {
  1. Public:
  1.     DECLARE_META_INTERFACE(MyService);
  1.        
  1.     Virtual fun1() = 0;
  1.     Virtual fun2() = 0;
  1. }

 

(3)定义一个本地实现类BnMyService

在IMyService.h头文件里定义接口实现类BnMyService, 需继承自BnInterface,间接双继承了IMyService接口类和BBinder类,代码例如以下:

  1. Class BnMyService:public BnInterface<IMyService>
  1. {
  1. Public:
  1.     Virtual status_t onTransact(uint32_t code,
  1.                                     const Parcel& data,
  1.                                     Parcel* reply,
  1.                                     uint32_t flags = 0);
  1. }

(4)定义本地代理类BpMyService

在IMyService.cpp源文件里,定义接口代理类BpMyService,需继承自BpInterface。BpMyService能够提供IMyService接口所定义的接口函数。

  1. class BpMyService: public BpInterface<IMyService>
  1. {
  1. public:
  1.     BpMyService(const sp<IBinder>& impl)
  1.         : BpInterface<IMyService>(impl)
  1.     {
  1. }
  1. void fun1()
  1.     {
  1.         Parcel data, reply;
  1.         ……            //数据写入
  1.         remote()->transact(枚举量, data, &reply);
  1.         return ……     //数据返回
  1.     }
  1. ……
  1. }

(5)增加宏定义

在IMyService.cpp源文件里,增加宏定义IMPLEMENT_META_INTERFACE()

  1.  
  1. IMPLEMENT_META_INTERFACE(MyService, "XXX");
  1.  

(6)定义BnMyService的onTransact()函数

在IMyService.cpp源文件里实现接口实现类BnMyService,当中onTrasact()函数依据功能代码枚举量的不同分别运行不同的功能调用。

  1. status_t BnMyService::onTransact(
  1.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
  1. {
  1.     switch(code) {      //code功能代码枚举量
  1.         case功能代码枚举量: {
  1.             LOGV("NOTIFY_CALLBACK");
  1.             CHECK_INTERFACE(ICameraClient, data, reply);    //检查描写叙述符字符串
  1.             ……        //參数输入,接口函数功能的真正实现
  1.             reply->……);   //返回数据
  1.             return NO_ERROR;
  1.         } break;
  1. ……
  1. default:
  1.             return BBinder::onTransact(code, data, reply, flags);
  1. }

(7)创建真正的本地接口实现类MyService类

在头文件里定义类MyService,继承自BnInterface,定义功能函数和初始化函数instantiate():

  1. Class MyService:public BnMyService
  1. {
  1. Public:
  1.     Static void instantiate();
  1.    
  1.     Virtual func1();
  1.     Virtual func2();
  1.     ……
  1. }
  1.  

(8)定义MyService::instantiate()函数

  1. void MyService::instantiate() {
  1.     defaultServiceManager()->addService(
  1.             String16("newservice"), new MyService());
  1. }
  1.    

(9)服务进程中注冊服务

在服务进程A初始化时增加MyService:: instantiate()函数,注冊服务,调用joinThreadPool()函数进入循环等待调用,侦听请求、处理请求。

  1. int main(int argc, char** argv)
  1. {
  1.     sp<ProcessState> proc(ProcessState::self());
  1.     sp<IServiceManager> sm = defaultServiceManager();
  1.     LOGI("ServiceManager: %p", sm.get());
  1.     MyService::instantiate();
  1.     ……
  1.     ProcessState::self()->startThreadPool();
  1.     IPCThreadState::self()->joinThreadPool();
  1. }

(10)client获取服务代理对象

client进程B要想和服务端通讯,首先须要获取服务管家ServiceManager的代理对象,,然后查找服务,由于服务已经注冊,所以会返回一个该服务代理对象的引用,此代理对象中包括一个指向查找的服务的handle句柄。

  1. const sp<IMyService>& MyServiceSystem::get_MyService()
  1. {
  1.     Mutex::Autolock _l(mLock);
  1.     if (gMyService.get() == 0) {
  1.         sp<IServiceManager> sm = defaultServiceManager();    //获取服务管家的代
  1. //理对象
  1.         sp<IBinder> binder;
  1.         do {
  1.             binder = sm->getService(String16("newservice")); //查找到服务后,
  1. //返回服务的代理对象
  1.             ……
  1.         } while(true);
  1.         ……
  1.         gMyService = interface_cast<IMyService>(binder);    //将其转换为本地服
  1. //务代理对象(BpMyService)
  1.         ……
  1.     }
  1.     ……
  1.     return mMyService;
  1. }

(11)client调用服务端函数

client进程B调用IMyService的接口函数,调用会传递给包括了服务对象handle的代理对象BpBinder,写入binder内核驱动。binder驱动知道数据传递到的对象,于是将数据传递给进程A。

服务端进程A从binder驱动中读取数据,然后处理远程调用,然后发送reply数据给binder驱动。binder驱动将reply传递给client进程B。进程B从binder驱动中读取数据并最终获取到reply,从而完毕进程通信。

  1. Status_t MyServiceSystem::func1()
  1. {
  1.     Const sp<IMyService>& af = MyServiceSystem::get_MyService();
  1.     Af::Func1();
  1.     ……
  1. }

到这里,我们已经把android中的binder机制介绍完了。呵呵,本来认为binder机制总结起来不会非常难,可在写总结的过程中还是遇到了非常多问题。呵呵,只是还好,都差点儿相同一一攻克了,最终写完了。总结过程中相当于又学了一边binder机制,并且还有新的收获,真的不错哦!

android binder机制之——(创建binder服务)的更多相关文章

  1. 【转】Android - Binder机制

    以下几篇文章是分析binder机制里讲得还算清楚的 目录 1. Android - Binder机制 - ServiceManager 2. Android - Binder机制 - 普通servic ...

  2. Android 进阶8:进程通信之 Binder 机制浅析

    读完本文你将了解: IBinder Binder Binder 通信机制 Binder 驱动 Service Manager Binder 机制跨进程通信流程 Binder 机制的优点 总结 Than ...

  3. Android系统Binder机制学习总结

    一.Binder机制概述 在Android开发中,很多时候我们需要用到进程间通信,所谓进程间通信,实现进程间通信的机制有很多种,比如说socket.pipe等,Android中进程间通信的方式主要有三 ...

  4. Android应用中创建绑定服务使得用户可以与服务交互

    原文:http://android.eoe.cn/topic/android_sdk 一个绑定的服务是客户服务器接口上的一个服务器.一个绑定的服务允许组件(如:活动)来绑定一个服务,传送请求,接收响应 ...

  5. AIDL Service Android进程间通信机制

    转载出处:http://www.apkbus.com/home.php?mod=space&do=blog&uid=664680&id=59465 我们知道,在Android ...

  6. 自顶向下分析Binder【1】—— Binder实例篇

    欢迎转载,转载请注明:http://blog.csdn.net/zhgxhuaa 一个Binder实例 我们Binder的学习将从以下的一个实例開始.依据Android文档中的描写叙述,创建一个Bin ...

  7. 快速了解Android重要机制

    转自 http://www.jianshu.com/p/5f6d79323923 一.Android系统底层研究 关于底层的知识点不是在一篇文章中能讲解清楚,参见本人的Android底层研究系列,不断 ...

  8. Android中的Binder机制的简要理解

    转载自:http://www.linuxidc.com/Linux/2012-07/66195.htm http://blog.csdn.net/sunxingzhesunjinbiao/articl ...

  9. Android深入浅出之Binder机制

    一说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的.所以搞明白Binder的话,在很大程度上就能理解程序运行 ...

随机推荐

  1. linux下的二进制文件的编辑和查看

    linux下的二进制文件的编辑和查看 http://blog.csdn.net/wangxiaoqin00007/article/details/6618003 一.在Linux下查看二进制文件的软件 ...

  2. 小记:css特殊性

    今天早上遇到了个小bug,刚好用从css权威指南学到的知识解决了 html结构 <ul class="portlet-nav"> <li><a id= ...

  3. 读书笔记:php_tizag_tutorial

    昨天在实验室花了一天时间看了英文版的php_tizag_tutorial,因为上学期用php和bootstrap写过一个租房网站,对php还是比较熟悉.现在总结一下php_tizag_tutorial ...

  4. Windows Phone 8初学者开发—第20部分:录制Wav音频文件

    原文 Windows Phone 8初学者开发—第20部分:录制Wav音频文件 原文地址:http://channel9.msdn.com/Series/Windows-Phone-8-Develop ...

  5. c语言利用指针计算字符串的长度

    可以用strlen函数,这里我们自己写一个. 注意:不能用scanf,scanf一遇到空格就认为输入结束.应该用gets(),遇到换行符或EOF结束.说明可以接受空格. #include<cst ...

  6. mysql tcp 4层负载

    -bash-4.1# cat /etc/haproxy/haproxy.cfg global log 127.0.0.1 local3 maxconn 65535 chroot /usr/local/ ...

  7. UVALive 6584 Escape (Regionals 2013 >> Europe - Central)

    题目 给出一棵树,每个节点有一个怪物或血药,遇到怪物必须打,打完后扣掉一定的血量. 一开始英雄的血量为\(0\),当血量小于\(0\)时就挂了. 给出英雄的起点和终点,问能否成功到达终点. 算法 这题 ...

  8. ETC_百度百科

    ETC_百度百科 ETC(电子不停车收费系统)

  9. Mac中MacPorts安装和使用

    文章转载至http://www.zikercn.com/node/8 星期四, 06/07/2012 - 19:02 - 张慧敏 MacPorts简单介绍 MacPorts,以前叫做DarwinPor ...

  10. 搭建python集成开发环境.

    需要搭建的内容一共有三项, python ,wxpython 以及spe.     其中spe 是python 的可视化集成开发环境(ide) , 其需要python GUI图形库wxpython的支 ...