Android 内核初识(8)Binder

时间:2022-03-16 21:51:32

简介

  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

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. JSon_零基础_006_将JSon格式的字符串转换为Java对象

    需求: 将JSon格式的字符串转换为Java对象. 应用此技术从一个json对象字符串格式中得到一个java对应的对象. JSONObject是一个“name.values”集合, 通过get(key ...

  2. The Zen Programmer (zhuan)

    http://blog.csdn.NET/marksinoberg/article/details/52460725 ***************************************** ...

  3. JAVA日历

    效果图如下: import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import ...

  4. ADO.NET之使用DataGridView控件显示从服务器上获取的数据

    今天回顾下ADO.NET中关于使用DataGridiew控件显示数据的相关知识 理论整理: 使用 DataGridView 控件,可以显示和编辑来自多种不同类型的数据源的表格数据. SqlDataAd ...

  5. jquery1.9学习笔记 之层级选择器(一)

    子选择器(“parent > child”) 描述:选择所有父元素的直系子元素. 例子: <!doctype html> <html lang='zh'> <hea ...

  6. Swift3&period;0 函数闭包与OC Block

    刚接触Swift,如有不对的点,欢迎指正.转载请说明出处 定义一个基本函数 //定义一个函数,接收一个字符串,返回一个String类型的值 func test(name:String) -> S ...

  7. vue 使用定时器setInterval

    来自:https://www.jianshu.com/p/180957762852 侵删 beforeMount() { //车辆进出设置定时器,每3秒刷新一次 var self = this; cl ...

  8. php5&period;5&period;7添加pgsql&comma;pdo&lowbar;pgsql&comma;swoole

    一:下载php源码sudo wget cn2.php.net/distributions/php-X.X.X.tar.gz 二:解压 tar xzf /php-X.X.X.tar.gz 三:进入源码e ...

  9. 高性能mysql 第六章查询性能优化 总结(上)查询的执行过程

    6  查询性能优化 6.1为什么查询会变慢 这里说明了的查询执行周期,从客户端到服务器端,服务器端解析,优化器生成执行计划,执行(可以细分,大体过程可以通过show profile查看),从服务器端返 ...

  10. Queuing HDU2604

    一道递推题目 得到递推关系为  f[n]=f[n-1]+f[n-3]+f[n-4]; 用普通的枚举算法会超时 所以要用矩阵快速幂来加速 转化为矩阵即为: +1 0 1 1       F(N-1) F ...