Binder初理解:
参考:http://blog.csdn.net/luoshengyang/article/details/6618363
通过罗大牛的文章,我们知道,Binder是作用于通信的。相对于binder,我们更熟悉使用广播进行通信。
他们之间有什么联系?
http://www.cnblogs.com/lwbqqyumidi/p/4168017.html
里面提到:
广播接受者通过Binder机制进行注册和发送广播。
既然有了广播,那么Binder还有用吗?
暂时还不知道,先学习一下Binder:
Binder的架构图
这是所谓通过Binder的远程通信,其实就是不同进程之间的通信,但是中间有个Binder,和ServiceManager
Binder是一个调用接口。
这是对Binder的大致概念。
博客http://blog.sina.com.cn/s/blog_73799d980101sa48.html中提出:
1:Binder框架定义了四个角色:Server,Client,ServiceManager(以后简称SMgr)以及驱动。其中 Server,Client,SMgr运行于用户空间,驱动运行于内核空间。这四个角色的关系和互联网类似:Server是服务器,Client是客户终端,SMgr是域名服务器(DNS),驱动是路由器。
2:Binder驱动虽然默默无闻,却是通信的核心。尽管名叫‘驱动’,实际上和硬件设备没有任何关系,只是实现方式和设备驱动程序是一样的:它工作于内核态,提供open(),mmap(),poll(),ioctl()等标准文件操作
3:ServiceManager 与实名Binder
SMgr的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder 名字获得对Server中Binder实体的引用。注册了名字的Binder叫实名Binder,就象每个网站除了有IP地址外都有自己的网址。Server创建了Binder实体,为其取一个字符形式,可读易记的名字,将这个Binder连同名字以数据包的形式通过Binder驱动发送给 SMgr,通知SMgr注册一个名叫张三的Binder,它位于某个Server中。驱动为这个穿过进程边界的Binder创建位于内核中的实体节点以及 SMgr对实体的引用,将名字及新建的引用传递给SMgr。SMgr收数据包后,从中取出名字和引用填入一张查找表中。
*****注意上面说的:Server创建了Binder实体,为其取一个字符形式,可读易记的名字,将这个Binder连同名字以数据包的形式通过Binder驱动发送给 SMgr,通知SMgr注册一个名叫张三的Binder,它位于某个Server中。
再看这张图:
结合分析:
1:一个服务(Server)创建了一个Binder实体,并为其取了一个名字(引用)
2:服务在Binder驱动中创建了代理Binder接口和引用
3:服务通过0号引用将Binder实体和引用注册到了ServiceManger中,用于管理
4:Client通过0号引用和服务名称请求ServiceManger来获取Binder实体的引用。
5:Client通过获取的引用找到代理Binder接口,传递数据
6:代理Binder接口通过映射找到对应的Server,Server解析传递过来的数据,调用方法处理数据。返回结果
(说实话,看到这里有了大概理解,下面讲的略深,我只是做了总结,还不是很明白)
罗神推荐了值得学习的博客:深入浅出Binder:
参看:http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html
这篇文章中提到了《深入理解Android 卷一》中的第六章:深入理解Binder,那么我们就从这里入手:
进一步理解Binder:
(这一部分还未理解明白,感觉略深)
1:简单分析
首先,Binder通信是C/S架构的,也就是Client和Server。
a:我们的Server需要注册服务到ServiceManager,我们可以看做Server是ServiceManager的客户端
b:我们的Client要使用服务就要到ServiceManager中查询,看做Client是ServiceManager的另一个客户端。
c:然后Client通过查询得到的服务信息与注册的Server建立通信,直接使用Server服务,所以Client又是Server的客户端。
最后,但是三者都是基于Binder通信的,这样就对Binder架构图有了基本的理解。
2:逐步分析:
书中举例分析了MediaServer怎么实现了Binder通信:
c++代码:
第一步:
ProcessState,按照字面是:进程状态,那么一个进程当前只能有一个状态。
书中对第一步做了更深入的分析,包括上面的哪一篇博客也是,但是这里我只想知道做了什么:
1):打开Binder设备
2):Binder分配内存接受数据
3):因为ProcessState是唯一的,所以一个进程只打开设备一次。
第二步:
defaultServiceManager与IServiceManager
defaultServiceManager函数会返回一个IServiceManager对象
A:defaultServiceManager
书中分析得到defaultServiceManager中有函数创建了BpBinder。
那么BpBinder是做什么用的。
书中提到:BpBinder与BBinder是与Binder相关的通信类,是从IBinder类中派生出来的:
BpBinder是客户端与服务交互之间的代理类,p即Proxy
BBinder是与Proxy相对的另一端,它是proxy交互的目的端。
注意:BBinder与BpBinder是一一对应的,某个BpBinder只能与对应的BBinder交互。他们之间通过handler来标识
B:IServiceManager
书中通过对代码的逐层分析,说到又通过defaultServiceManager函数中创建的BpBinder对象作为参数创建了一个BpServiceManager。
1,IServiceManager,BpServiceManager和BnServiceManager与业务逻辑相关
2,BnServiceManager同时从IServiceManager和BBinder中派生,可以直接参与通信。但是它是一个虚类,业务函数最终需要子类实现
3,BpServiceManager向上似乎找不到BpBinder
书中提到,BpRefBase中的mRemote就是BpBinder。
不管你信不信,反正我信了。因为里面的分析貌似很复杂,我还不能判断。
BpServiceManager实现了IServiceManager的业务函数;
BpServiceManager中的mRemote又是BpBinder,BpBinder是通信的代表。
最后知道:
通过defaultServiceManager,我们得到两个关键对象:
1,BpBinder,它的标识handler值为0
2,BpServiceManager,它的mRemote值是BpBinder。
BpServiceManager是IServiceManager子类,实现了IServiceManager的业务函数,而BpBinder又是通信代表。
第三步:
注册MediaPlayerService:注册的内部过程暂不关心
ServiceManager:
ServiceManager存在的意义:
1,能集中管理系统内的所有服务,能施加权限控制,不是任何进程都能注册服务的
2,支持通过字符串名称查找相应的Service
3,因为服务进程有可能挂掉,客户端通过ServiceManager查找Server信息和状态
发现图中和前面的总结中,似乎都是系统自动生成的。
在MediaService中:
1,BpMediaPlayer,由MediaPlayerClient使用,调用IMediaPlayer提供的业务
2,BnMediaPlayer,由MediaPlayerService使用,处理Client端的业务请求
总结:
看到最后,我们可以这么理解:
A进程中的Client需要与B进程中的Server交互
B进程中的Server要通过Binder驱动注册到ServiceManager
Binder驱动开辟空间接受数据,产生代理BpBinder。
还有通过BpBinder对象创建的管理BpServiceManager
最终我们进行直接交互的其实是代理与Client。
代理将Client发送的参数发给Binder Driver,Server读取Binder Driver中的数据,发现是发给自己的时候,处理,返回。
参考http://blog.csdn.net/coding_glacier/article/details/7520199