Binder机制(1)

参考:

http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html


基于Binder通信的C/S架构体系中,除了C/S架构所包括的Client端和Server端外,Android还有一个全局的ServiceManager端,它的作用是管理系统中的各种服务(Service)。这三者的关系如下:


注意:一个Server进程可以注册多个Service.


选择MediaServer做为切入点,因为这个Server是很多重要的Service的栖息地。包括:

AudioFlinger :音频系统的核心服务

AudioPolicyService:音频系统中关于音频策略的重要服务

MediaPlayerService: 多媒体系统的重要服务(本节以这个为例

CameraService: 有关摄像 / 照相的重要服务


这里以MediaPlayerService 为切入点,先分析MediaServer本身。

MediaServer(MS)是一个可执行程序,入口函数是main,代码如下:


上面代码有5个关键点。下面一一分析。

一、ProcessState

每个进程只有一个ProcessState,它是独一无二的。

sp<ProcessState> proc(ProcessState::self());
关于sp<> ,wp<>的用法可以参考: http://blog.csdn.net/lksodit_yiyi/article/details/8086059

定义了一个ProcessState sp指针proc,并为proc赋值为ProcessState::self()。下面看下其实现:

ProcessState的构造:

这个构造函数很重要,它悄悄地打开了Binder设备。代码如下:



打开binder设备:

open_driver的作用就是打开/dev/binder这个设备。它是Android在内核中为完成进程间通信而专门设置的一个虚拟设备。实现如下:


到这里ProcessState::self函数分析完成,总结:

1. 打开/dev/binder设备,这就相当与与内核的Binder驱动有了交互的通道

2. 对返回的fd使用mmap,这样Binder驱动就会分配一块内存来接收数据。

3. 由于ProcessState具有唯一性,因此一个进程只打开设备一次。


二、defaultServiceManager

defaultServiceManager函数的实现在IServiceManager.cpp中完成,它会返回一个IServiceManager对象,通过这个对象,就可以与ServiceManager进行交互了

下面看看这个函数的实现:


interface_case相关可以参考:http://blog.csdn.net/myarrow/article/details/7054589

我了解的意思是创建一个IServiceManager对象。

调用了ProcessState的getContextObject函数。


getStrongProxyForHandle 这个函数的调用参数名叫handle。它是对资源的一种标识。说白了,其实就是有一个资源项,保存在一个资源数组中,handle的值正式该资源项在数组中的索引。


上面的BpBinder是什么?

BpBinder和BBinder都是Android中与Binder通信相关的代表它们都是从IBinder类中派生而来。


1. BpBinder是客户端与Server交互的代理类,p即Proxy的意思

2. BBinder是与proxy相对的一端,它是proxy交互的目的端。如果说Proxy代表客户端,那么BBinder则代表服务端,这里的BpBinder和BBinder是一一对应的,即某个BpBinder只能和对应的BBinder交互。我们当然不希望通过BpBinderA发送的请求,却由BBinderB来处理。


刚才在defaultServiceManager中创建了这个BpBinder。这里有两个问题:

1. 为什么创建的不是BBinder?

因为我们是SeviceManager的客户端,档案使用代理端和ServiceManger进行交互。

2. BpBinder和BBinder是一一对应的,那么BpBinder如何标识它所对应的BBinder端呢?

答案: Binder系统通过handler来标识对应的BBinder。以后我再确认这个Handle值的作用。

注意: 这里我们给BpBinder构造函数传的参数handle的值是0.这个0在整个Binder系统中有重要含义:0代表的就是ServiceManager所对应的BBinder

BpBinder是如此重要,必须对它进行深入分析,代码如下所示:


仔细查看,发现BpBinder,BBinder这两个类没有任何地方操作ProcessState打开的那个/dev/binder设备,换言之,这两个Binder类没有和binder设备直接交互。

为什么说BpBinder与通信相关呢?

BpBinde只是个道具,它的后面一定另有机关

下面看下道具的出场过程:


现在这个函数调用将变成如下所示的样子:


这里的interface_cast是一个障眼法,下面进行分析。

interface_case的具体实现:


下面看看IServiceManager

(1) 定义业务逻辑

IServiceManager定义在IServiceManager.h中,代码如下:


(2)业务与通信的挂钩:

Android巧妙地通过DECLARE_META_INTERFACEIMPLENT宏,将业务和通信牢牢地钩在了一起。他俩都定义在IInterface.h中。先看DECLARE_META_INTERFACE这个宏,如下所示:


将IServiceManager的DECLARE宏进行相应的替换后得到的代码如下所示:


DECLARE宏声明了一些函数和一个变量,那么IMPLEMENT宏的作用肯定就是定义它们了。IMPLEMENT的定义在IInterface.h 中,IServiceManager是如何使用这个宏的呢?只有一行代码,在IServiceManager.cpp中。如下所示:


将这个宏展开,如下所示:


之前疑问:interface_case是如何把BpBinder指针转换为一个IServiceManager指针的。答案就在asInterface函数的这一行代码中,如下所示:


interface_cast不是指针的转换,而是利用BpBinder对象作为参数新建了一个BpServiceManager对象。我们已经直到BpBinder和BBinder与通信有关系,这里怎么突然冒出来一个BpServiceManager?他们有什么关系?


IServiceManager家族

要搞清楚上面问题,必须先了解IServiceManager家族之间的关系。下图展示了IServiceManager的家族图谱:


1. IServiceManager,BpServiceManager和BnServiceManager都与业务逻辑相关

2. BnServiceManager同时从IServiceManager BBinder派生,表示它可以直接参与Binder通信

3. BpServiceManager虽然从BpInterface中派生,但是这条分支似乎与BpBinder没有关系

4. BnServiceManager是一个虚类,它的业务函数最终需要子类来实现。


在上图中的BpServiceManager,既然不像BnServicemanager哪样与Binder有直接的血缘关系,那么它是如何与Binder交互的呢?简言之,BpRefBase中的mRemote值就是BpBinder


BpInterface的实现代码如下所示:


BpRefBse()的实现如下所示:


原来,是BpServiceManager的一个变量mRemote指向了BpBinder。至此,我们的魔术结束。回想defaultServiceManager函数,可以得到一下两个关键对象:

1. 有一个BpBinder对象,它的handle值是0

2. 有一个BpServiceManager对象,它的mRemote值是BpBinder。

BpServiceManager对象实现了IServiceManager的业务函数,现在又有BpBinder作为通信的代表,接下来的工作就简单了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值