简介

  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这三者之间的交互关系,如图所示

注意:一个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类中派生而来,如图


· 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的家族

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

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

Binder通信层和业务层的关系

Android 内核初识(8)Binder的更多相关文章

  1. 【转】Android 内核初识(6)SystemServer进程

    简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...

  2. Android 内核初识(6)SystemServer进程

    简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...

  3. Android 内核初识(5)Zygote进程

    简介 Zygote本身是一个Native的应用程序,和驱动.内核等均无关系.Zygote是由init进程根据init.rc文件中的配置项而创建的. zygote最初的名字叫“app_process”, ...

  4. Android 内核初识(3)init进程

    init是一个进程,确切地说,它是Linux系统中用户空间的第一个进程.由于Android是基于Linux内核的,所以init也是Android系统中用户空间的第一个进程,它的进程号是1.作为天字第一 ...

  5. Android 内核初识(1)下载源码需求与教程

    官方文档: http://source.android.com/source/requirements.html  Requirements The Android build is routinel ...

  6. Android 内核初识(7)RefBase、LightRefBase、sp和wp

    简介 RefBase是Android中所有对象的始祖,类似MFC中的CObject及Java中的Object对象.在Android中,RefBase结合sp和wp,实现了一套通过引用计数的方法来控制对 ...

  7. Android 内核初识(4)属性服务器

    简介 Windows平台上有一个叫注册表的东西.注册表可以存储一些类似key/value的键值对.一般而言,系统或某些应用程序会把自己的一些属性存储在注册表中,即使下次系统重启或应用程序重启,它还能够 ...

  8. Android 内核初识(2)android系统架构

    以模块角度 以Java,native,kernel角度

  9. 写给 Android 应用工程师的 Binder 原理剖析

    写给 Android 应用工程师的 Binder 原理剖析 一. 前言 这篇文章我酝酿了很久,参考了很多资料,读了很多源码,却依旧不敢下笔.生怕自己理解上还有偏差,对大家造成误解,贻笑大方.又怕自己理 ...

随机推荐

  1. WIN8+VS2013编写发布WCF之一(编写)

      引言:上学期因为写服务器用WCF,所以连查资料再瞎调试勉强成功了,但是这学期又到了用WCF的时候,而当时的资料零零散散,查找不易,并且此次是在WIN8与VS2013环境下编写的,所以将该入门过程记 ...

  2. JavaScript学习笔记(8)——JavaScript语法之运算符

    一. 算术运算符: 运算符 描述 例子 结果 + 加 x=y+2 x=7 - 减 x=y-2 x=3 * 乘 x=y*2 x=10 / 除 x=y/2 x=2.5 % 求余数 (保留整数) x=y%2 ...

  3. Codevs 1684 垃圾陷阱

    1684 垃圾陷阱 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 卡门--农夫约翰极其珍视的一条Holsteins奶牛--已经落了 ...

  4. OpenJudge/Poj 2105 IP Address

    1.链接地址: http://poj.org/problem?id=2105 http://bailian.openjudge.cn/practice/2105 2.题目: IP Address Ti ...

  5. 微软自带iscsi客户端对iqn的要求

    节点名称:Microsoft iSCSI 发起程序严格遵守为 iSCSI 节点名称指定的规则.这些规则也适用于 Microsoft iSCSI 发起程序节点名称以及发现的任何目标节点名称.构建 iSC ...

  6. Linux中的时间和时间管理

    Coordinated Universal Time(UTC):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间(Greenwich Mean Time,GMT).比如,中国内地的时 ...

  7. Qwt的编译与配置

    QWT,全称是Qt Widgets for Technical Applications,是一个基于LGPL版权协议的开源项目, 可生成各种统计图.它为具有技术专业背景的程序提供GUI组件和一组实用类 ...

  8. mysql 之权限介绍

    转自:http://tech.it168.com/a2010/0114/837/000000837456_all.shtml 一.MySQL授权表概述首先从全局开始,如果全局的是允许的,即在 user ...

  9. c/c++中的各种字符串转换

    一:CString 和 *char 的转换: 1:CString -> *char 1)CString转化为*char可以使用CString中的GetBuffer()函数,具体如下: CStri ...

  10. Linux下GPIO驱动(四) ----gpio_request();gpio_free();

    //gpio_request申请gpio口 int gpio_request(unsigned gpio, const char *label) { struct gpio_desc *desc; s ...