从驱动层分析android的Binder机制-android学习之旅(83)
前言及知识准备
Binder驱动程序
Service组件的注册和启动
Clinet应用获取服务
本次主要介绍Android平台下Binder进程间机制。从机制的组成出发,将按照Binder驱动程序、Binder服务的注册和启动、Client应用获取服务三个方面来讲述。最后针对该模块提出了自己的问题以及思考
首先介绍Binder机制的组成。
第一部分就是Binder驱动程序,它存在于内核层,是服务提供者和服务使用者用来交互的“桥梁”
第二部分是server,顾名思义,是用来提供服务的
第三部分是Client,就是使用服务的应用
第四部分就是Service Manager。比较特殊,后面详述。
Client、Server、Service Manager都是在用户空间的。如下图:
Service Manager是Binder机制中的关键组成部分,是Service的管理者。当一个应用想要提供服务时,首先要向Service Manager注册,然后再启动;而Client想要获取服务时,也需要向Service Manager进行查询,获取服务。
但是Service Manager实际上也是一种server,只不过功能较为特殊。
一个完整的Binder机制通信过程如下:
1、Binder设备进行初始化
2、实例化Service Manager对象,并且打开Binder设备
3、为打开的Binder设备分配内存
4、将Service Manager向binder驱动程序注册,成为Binder的上下文管理者
5、Service组件向Service Manager注册服务,循环等待client进程请求
6、启动Binder服务线程,并且加入线程池中
7、Client应用从Service Manager获取相关服务的代理对象即指针,并且向其传递服务命令
8、Service组件完成服务返回信息给client
9、Client停止使用服务,当Service组件无应用使用时,终止服务。**重点内容**
介绍驱动层的结构体
结构体binder_buffer
这个结构体是用来描述内核缓冲区,即缓冲区的分配信息。在为Binder设备分配内存时,便会维护这样一个结构体列表。
部分结构体如下:
Entry保存的是缓冲区列表
的节点;rb_node是空闲/
正在使用缓冲区的节点,其他变量我们不关心。
后半部结构体如下,其中transaction变量,用于描述此缓冲区交给了哪个事务。
target_node描述此缓冲区交给了哪个Binder对象使用
data指向了一块数据
缓冲区,data_size为
其大小。Offset_size
用于寻找数据data中的Binder对象。
binder_transaction_data结构体
用来描述进程间通信过程中所使用的数据的。
联合体target
描述的是一个
目标Binder
对象
Cookie是一个附加数据,code是通信双方约定好的通信代码
Pid与euid是发送端的进程和线程ID号
data_size与
offset_size和前面
用法一样。
联合体data指向数
据缓冲区。Offsets
变量记录着缓冲区中
Binder结构体的位置
flat_binder_object结构体
描述一个Binder对象的结构体,通常存在于通信数据缓冲区中。
Type说明此Binder
对象类型
Flag为通信时所需
的各种标志,如优
先级、文件描述等。
Binder与handle组成的联合体。当此结构体指向一个Binder实体对象时,使用Binder表示;如果
指向的是一个Binder
引用对象,则使用
Handle表示。
Client进程和server进程的一次进程间通信分为如下五步:
1.client进程将通信数据封装,以便传递给Binder驱动程序
将如下信息封装入parcel类型的结构体中:
①Strict Mode Policy也就是通信双方约定的协议,比如进制磁盘操作等等;
②服务接口描述符,用于server判断是否为自己需要处理的服务请求;
③service组件的名称,用于Binder驱动程序识别组件并且传递消息
④ flat_binder_object结构体。将目标service组件封装成次结构体即可。
⑤通信双方约定好的通信指令。
将以上数据写入封装好之后,就交给Binder驱动程序来处理。
2.client进程向Binder驱动发送一个请求服务(BC_TRANSACTION)的命令,Binder驱动首先将传递进来的parcel类型数据封装成binder_transaction_data结构体,并且根据协议内容,将数据写入内核缓冲区,并且找到相关server进程之后,返回一个请求完成消息(BR_TRANSACTION_COMPLETE)给client进程,表示已经接受
3.Binder驱动程序将client进程发来的通信数据复制到新的binder_transaction_data结构体中,传递给server进程,之后Binder驱动将待处理事务加入到server进程的事务序列中,并且并且向serve进程发送服务请求BR_TRANSACTION,唤醒server进程,请求目标server进完成通信请求。
4.server进程收到协议并进行处理之后,将处理结果、服务执行情况、需要返回的目标client进程封装成一个结构体,发送给Binder驱动,并且发送一个回应消息BC_REPLAY,Binder驱动收到后向server发送一个通信完成消息,表示通信结果已经收到,并且将通信结果拷贝到Client进程的缓冲区中,释放server进程内核缓冲区,此时server进程认为通信结束,准备下一次通信。
5.Binder驱动把通信结果返回给client进程,向client进程发送服务完毕消息,表示通信请求完成,client用户将内核缓冲区中的通信结果拷贝出来,并且进行相应处理。处理完成后,Binder驱动清理client进程申请的内核缓冲区。
至此完成全部的通信步骤,Binder驱动程序再次充当了一个传递者的角色。
Binder对象知识:
Binder本地对象(BBinder):用户空间创建,运行在server进程中。
Binder实体对象(binder_node):创建在Binder驱动程序中,是在内核层,被Binder本地对象所引用。
Binder引用对象(binder_ref):由Binder驱动创建,被用户空间中的client进程创建的代理对象所引用。
Binder代理对象(BpBinder):存在于用户空间中,被client进程所使用。会被其他client进程引用,也引用了Binder驱动程序中的Binder引用对象。
依赖关系如下图:
Binder代理对象依赖Binder引用对象,饮用对象依赖于实体对象,实体对象依赖于本地对象 。
一个Service组件想要注册服务,必须先启动Service Manager
1.打开Binder设备,方法如前面所述,
2.向Binder驱动注册,成为Binder上下文管理者。
3.注册成功之后,便进入循环等待相关进程访问。
如果server进程突然崩溃怎么办? ##、
答:当一个进程发现服务不可用时,可想Binder驱动程序递交死亡通知,驱动程序将该通知发送到各个使用服务的程序中。
Binder机制如何知道哪些进程使用了服务?
答:Binder机制在服务注册时为每个server继承维护了一个用于记录哪些client进程使用了这个服务的二叉树。
结构体binder_transaction_data以及binder_buffer,这些和内存相关的结构体,用户进程可以操作吗?可以的话,怎么操作?不可以的话,用户进程怎么对binder的内存缓冲区进行操作?
答:这两个数据结构都是定义在内核空间的。用户进程不允许直接操作这两个数据结构。
在client进程发送给Binder驱动时,驱动接收数据会首先进行数据转型,使用的是内核中的函数IPCThreadState类里的writeTransactionData函数进行数据转型,由此完成了binder_transaction_data的写入。当用户申请通信时,便会由驱动程序来完成写入该结构体的操作。
binder_buffer则是由Binder驱动程序来进行维护的,描述了一个内核缓冲区的使用情况,操作函数有Binder驱动程序控制。
从驱动层分析android的Binder机制-android学习之旅(83)的更多相关文章
- 阿里面试官:Android中binder机制的实现原理及过程?
Binder 是 Android 系统中非常重要的组成部分.Android 系统中的许多功能建立在 Binder 机制之上.在这篇文章中,我们会对 Android 中的 Binder 在系统架构中的作 ...
- Android系统Binder机制学习总结
一.Binder机制概述 在Android开发中,很多时候我们需要用到进程间通信,所谓进程间通信,实现进程间通信的机制有很多种,比如说socket.pipe等,Android中进程间通信的方式主要有三 ...
- android布局Relative和gridLayout-android学习之旅(十六)
Relative布局简介 相对布局的组件是由兄弟组件和父组价决定的,因此这种布局被称为相对布局. 属性设置介绍 RelativeLayout.Layoutparam中只能设置为true和false的属 ...
- android布局##TableLayout和FrameLayout-android学习之旅(十五)
TableLayout 表格布局 tablelayout简介 表格布局有TableLayout代表,但是它的本质定义仍然是线性管理器.表格布局采用行和列来管理UI,但是不需要明确的定义多少行,多少列, ...
- Android广播接收器Broadcast Receiver-android学习之旅(十二)
首先继承BroadcastReceiver类,并在manifest中注册 public class MyReceiver extends BroadcastReceiver { public MyRe ...
- Android下拉列表控件spinner-andoid学习之旅(十一)
废话不多说,下拉列表常用的就是spinner控件. 直接上代码: package peng.liu.testview; import android.app.Activity; import andr ...
- Android的AdapterViewFlipper和Stackview-android学习之旅(三十)
AdapterViewFlipper简介 AdapterViewFlipper继承了AdapterViewAnimater.每次只能显示一个组件,用showPrevious()和showNext()来 ...
- Android之Gallery和Spinner-Android学习之旅(二十九)
Spinner简介 spinner是竖直方向展开一个列表供选择.和gallery都是继承了AbsSpinner,AbsSpinner继承了AdapterView,因此AdaptyerView的属性都可 ...
- Android的ScrollView和HorizontalScrollView-android学习之旅(四十一)
HorizontalScrollView和ScrollView简介 ScrollView和HorizontalScrollView都继承于FrameLayout组件,两个都是容器,前者为里面的组件添加 ...
随机推荐
- 纪念 参与GitHub上第一个组织
颇为起伏的一天. 今天大连的风, 甚是喧嚣. 不过,很高兴,小项目被fork了,也成功成为了一个开源贡献者. https://github.com/HostsTools 组织 上的那个Windows- ...
- iOS开源加密相册Agony的实现(三)
简介 虽然目前市面上有一些不错的加密相册App,但不是内置广告,就是对上传的张数有所限制.本文介绍了一个加密相册的制作过程,该加密相册将包括多密码(输入不同的密码即可访问不同的空间,可掩人耳目).Wi ...
- Servlet再度学习
虽然Servlet已经使用很多了,但是一直都仅局限在其使用操作上. 最近有空想对它进行一个相对全面的了解. 下面是博主整理的一篇博文. 一.Servlet简介 Servlet(Server Apple ...
- win10+ubuntu双系统安装方案
网上有很多教程,大多是win7,win8的,我折腾了一天,今天终于都安装好了,折腾的够呛,很多人都说挺简单的,嗯其实的确很简单,很多人回复说安装不成功,很有可能就是电脑安全权限的问题,我用的是华硕的电 ...
- 如何找出Xcode中不同版本Swift的路径
我们知道Xcode中可能包含不知一个Swift的版本,那么我们如何找到它们对应的路径呢? 熟悉unix shell命令的童鞋都知道有一个find指令,在我们已知Xcode路径时,我们可以在其中找到Sw ...
- ROS机器人程序设计(原书第2版)补充资料 (拾) 第十章 使用MoveIt!
ROS机器人程序设计(原书第2版)补充资料 (拾) 第十章 使用MoveIt! 书中,大部分出现hydro的地方,直接替换为indigo或jade或kinetic,即可在对应版本中使用. MoveIt ...
- dos2unix批量转换的一种方法
Linux本身提供了dos2unix和unix2dos两个命令来实现Windows和Linux文件的转换. 少量文件转换: 对于单个或少量的文件转换,可以直接使用命令,如: dos2unix file ...
- Windows安装和使用fftw
FFTW是一个比较快的.非常出名的一个DFT的开源库. 本文探索安装和配置FFTW,用Visual Studio 2008来使用fftw. 第一步:下载最新的fftw库 这一步很简单,只要在googl ...
- CSDN帐号被封
感慨
- 两个activity或者activity和fragment传值
使用Fragment的时候可能需要在两个Fragment之间进行参数的传递,开始想着可以使用SharedPreferences进行处理,想想这些简单的参数没有必要使用这么麻烦的方式去实现,翻了一下Fr ...