Android 内核初识(8)Binder

简介

  Binder是Android系统提供的一种IPC(进程间通信)机制。由于Android是基于Linux内核的,因此,除了Binder外,还存在其他的IPC机制,例如管道和socket等。Binder相对于其他IPC机制来说,就更加灵活和方便了。Android系统基本上可以看作是一个基于Binder通信的C/S架构。Binder就像网络一样,把系统各个部分连接在了一起,因此它是非常重要的。

什么是Binder

Binder是android在内核中专门用于完成进程间通信而设置的一个虚拟设备(/dev/binder).

· ProcessState的构造函数悄悄地打开了Binder设备.每个进程只有一个ProcessState对象Process::self();
· 打开/dev/binder设备,这就相当于与内核的Binder驱动有了交互的通道。
· Binder的驱动代码在kernel/drivers/staing/android/binder.c中,另外该目录下还有一个binder.h头文件。
· /proc/binder目录下的内容可用来查看Binder设备的运行状况。
· 由于ProcessState的惟一性,因此一个进程只打开设备一次。

Client、Server和ServiceManager

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

Android 内核初识(8)Binder

注意:一个Server进程可以注册多个Service,就像即将讲解的MediaServer一样。
根据上图,可以得出如下结论:
· Server进程要先注册一些Service到ServiceManager中,所以Server是ServiceManager的客户端,而ServiceManager就是服务端了。
· 如果某个Client进程要使用某个Service,必须先到ServiceManager中获取该Service的相关信息,所以Client是ServiceManager的客户端。
· Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互了,所以Client也是Server的客户端。
· 最重要的一点是,三者的交互都是基于Binder通信的,所以通过任意两者之间的关系,都可以揭示Binder的奥秘。

  这里,要重点强调的是Binder通信与C/S架构之间的关系。Binder只是为C/S架构提供了一种通信的方式,我们完全可以采用其他IPC方式进行通信,例如,系统中有很多其他的程序采用的就是Socket或Pipe的方法进行进程间通信。很多初学者可能觉得Binder较复杂,尤其是看到诸如BpXXX、BnXXX之类的定义便感到头晕,这很有可能是把Binder通信层结构和应用的业务层结构搞混了。如果能搞清楚这二者的关系,完全可以自己实现一个不使用BpXXX和BnXXX的Service。须知,ServiceManager可并没有使用它们。

BpBinder和BBinder

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

Android 内核初识(8)Binder
· BpBinder是客户端用来与Server交互的代理类,p即Proxy的意思。
· BBinder则是proxy相对的一端,它是proxy交互的目的端。如果说Proxy代表客户端,那么BBinder则代表服务端。这里的BpBinder和BBinder是一一对应的,即某个BpBinder只能和对应的BBinder交互。我们当然不希望通过BpBinderA发送的请求,却由BBinderB来处理。
· Binder系统通过handler来对应BBinder,在整个Binder系统中handler为0代表的就是ServiceManager所对应的BBinder.

MS(MediaServe)与SM(ServiceManager)用binder通信示例

在MediaServer进程向ServiceManager进程注册MediaPlayerService为例

在MediaServer进程中:
1,构造一个ProcessState,用ProcessState::self(),每个进程中只有一个ProcessState
2,ProcessState::self()中打开binder设备.
3,defaultServiceManager函数得到一个IServiceManager,实际得到BpServiceManager,它是IServiceManager的后代.用来和ServiceManager进程用binder通信,IServiceManager实际是用interface_cast函数模板,利用BpBinder对象作为参数新建了一个BpServiceManager对象.
4,用getStrongProxyForHandle(handler的值,0代表ServiceManager的BBinder),BpBinder和BBinder是一一对应的.Binder系统通过handler来对应BBinder
5,Android巧妙地通过DECLARE_META_INTERFACE和IMPLENT宏,将业务和通信牢牢地钩在了一起.DECLARE_META_INTERFACE在IServiceManager内部声明了业务函数.

6,addService函数中把请求数据打包成data后,传给了BpBinder的transact函数,把通信的工作交给了BpBinder.

7,在BpBinder的transact函数中使用了IPCThreadState

每个线程都有一个IPCThreadState,每个IPCThreadState中都有一个mIn、一个mOut,其中mIn是用来接收
来自Binder设备的数据的,而mOut则是用来存储发往Binder设备的数据的。

在ServiceManager进程中:
1,binder_open,打开binder设备
2,binder_become_context_manager,成为manager
3,binder_loop,处理客户端发过来的请求。
4,接收到请求,交给binder_parse,最终会调用func来处理这些请求
5,通常往binder_loop中传的那个函数指针是svcmgr_handler.这函数可集中处理.

6,do_add_service这个函数,它最终完成了对addService请求的处理实现

ServiceManager存在的意义

为何需要一个ServiceManager,其重要作用何在?
· ServiceManger能集中管理系统内的所有服务,它能施加权限控制,并不是任何进程都能注册服务。
· ServiceManager支持通过字符串名称来查找对应的Service。这个功能很像DNS。第6章 深入理解Binder
· 由于各种原因,Server进程可能生死无常。如果让每个Client都去检测,压力实在太大。现在有了统一的管理机构,Client只需要查询ServiceManager,就能把握动向,得到最新信息。这可能正ServiceManager存在的最大意义吧。

IServiceManager的家族

Android 内核初识(8)Binder

· IServiceManager、BpServiceManager和BnServiceManager都与业务逻辑相关。
· BnServiceManager同时从BBinder派生,表示它可以直接参与Binder通信。
· BpServiceManager虽然从BpInterface中派生,但是这条分支似乎与BpBinder没有关系。
· BnServiceManager是一个虚类,它的业务函数最终需要子类来实现。

重要说明:以上这些关系很复杂,但ServiceManager并没有使用错综复杂的派生关系,它直接打开Binder设备并与之交互。

Binder通信层和业务层的关系

Android 内核初识(8)Binder

上一篇:redis夺命连环问2--谈谈你对redis的认识,越多越好。


下一篇:Ant自动构建