目录

前言及知识准备
Service组件结构
Clinet组件结构
与Binder驱动程序交互
总结
Binder进程间通信实例
问题

本次主要介绍Android平台下Binder进程间通信库。所谓通信库,就是Adroid在应用程序框架层中将各种Binder驱动操作封装成一个Binder库,应用程序可以方便地调用库中提供的接口进行通信。这次将介绍Binder库的结构以及相关知识。

在Binder库中,service组件用模板类BnInterface来描述,称之为一个Binder本地对象,对应在Binder驱动程序中的Binder实体对象;
client组件使用模板类BpInterface来描述,称之为一个Binder代理对象,对应在Binder驱动程序中的Binder引用对象

在使用Binder通信库进行开发service组件和client组件时,首先是要定义一个service组件接口,然后必须实现一个Binder本地对象类和Binder代理对象类,他们分别继承自模板类BnInterface和BpInterface。
例如首先定义服务接口IKeyService,然后定义一个Binder本地对象类BnKeyService和一个Binder代理对象类BpKeyService。分别继承各自的模板类。

模板类BnInterface源码定义如下

参数INTERFACE是一个由进程自定义的组件接口。
模板类继承了Bbinder类,它为本地对象提供了抽象的进程间通信接口。如下

BBinder 定义如下

上图只列出了两个重要的成员函数:
transact:当client使用的Binder代理对象通过Binder驱动向service使用的Binder本地对象发出通信请求时,Binder驱动程序会调用此函数。
onTransact:用来处理业务的分发以及进程间的通信请求。这种处理并不在这里实现,而是在其子类Binder本地对象类的子类,service组件类中实现的。
Binder本地对象类重写了父类BBinder中的onTransact函数,并且将这种操作分发到自己的子类,service组件类来处理。
可以注意到,BBinder类继承自IBinder类,IBinder类继承自RefBase类
继承了RefBase类的子类都可以使用强指针和弱指针来时维持生命周期,就是说,Binder本地对象通过引用计数来维护生命周期。
Binder机制所使用的引用机制比较复杂,功能就是当有进程使用此对象时,便会增加相应的引用计数,当使用完毕,便会减少相应的计数,当计数减少至0,则对该对象进行释放和销毁。用来防止忘记销毁,或是提早销毁而导致的程序崩溃。
至此,service组件的结构分析告一段落,接下来看client组件。

Client组件使用的BpInterface定义如下:

使用比较简单,继承了BpRefBase类,此类为Binder代理对象提供了抽象的进程间通信接口。源码如下:

BpRefBase定义如下

此类继承了RefBase类,同理,Binder代理对象也可以通过引用计数维护生命周期。
BpRefBase类中有一个重要的成员变量mRemote,它指向了一个BpBinder对象,可通过成员函数remote来获取。
BpBinder实现了BpRefBase类中的进程间通信接口
定义如右图

成员变量mHandle是一个整数,也是用来表示client组件的句柄值,通过成员函数handle获取。
每一个client组件在Biinder驱动程序中都有一个对应的Binder引用对象,而每一个Binder引用对象都有一个句柄值。Client组件就是通过句柄值mHandle,与Binder驱动中的Binder引用对象建立对应关系的。
至此,client组件结构也介绍完毕。
但是无论是service组件还是client组件,前面的定义都是在各自的组件内定义,通信时还是需要与Binder驱动交互的,在代码内部就表示为BBinder类或者是BpBinder类,通过与IPCThreadState类进行交互来完成的。
IPCThreadState类定义如下:

IPCThreadState定义如下

其中比较重要的函数self,功能介绍如下:

每个使用Binder进程间通信机制的进程都有一个Binder线程池,用来处理通信请求。池中的每一个Binder线程都存在一个IPCThreadState对象。函数self就是用来获取IPCThreadState对象的。
成员函数transact用于和Binder驱动交互,在函数内部,使用talkwithdriver函数完成交互操作。一方面向Binder驱动发送通信请求,一方面接受来自Binder驱动的通信请求
IPCThreadState类中一个重要的成员变量mProcess,指向一个ProcessState对象,负责初始化Binder设备,即打开设备文件,并且将这个设备映射到进程的地址空间。
ProcessState对象
定义如右图

成员函数self用来获取进程中的ProcessState对象,
打开Binder设备之后用成员变量mDriverFD保存其描述符。
完成设备文件的映射,
即分配完内存缓冲区
后,地址保存在变量
nVMStart内。

Service组件原理图如下,以keyService为例

client组件原理图如下,以KeyService为例

上图中:
IKeyService为Service组件和client组件都要实现的接口;
BnKeyService为Service组件要继承的Binder本地对象类;
BpKeyService为client组件要继承的Binder本地代理类。
KeyService为一个Service组件。
Binder通信库中的service组件和client组件虽然结构都很复杂,但是其主要目标就是按照各自的功能,完成对于一个共同的服务接口的不同实现。Service组件通过服务接口来提供服务,client组件通过服务接口对于服务进行访问。
在组件中,各自完成了与Binder驱动程序的交互。
此次使用基于应用程序框架层提供的Binder库开发一个Binder进程应用实例。包含一个Server进程和Client进程。
 Server进程实现了一个service组件,功能是对一个虚拟硬件设备freg的寄存器val进行管理,并且向Client进程提供访问服务。
为了简化操作,将虚拟硬件设备的寄存器简化为一个整数型变量。

1. Android源代码的编译命令有哪些?mmm指令作用是什么?

答:编译命令有:
①m:编译所有的模块
②mm:编译当前目录下的模块,当前目录下要有Android.mk文件
②mmm:编译指定路径下的模块,指定路径下下要有Android.mk文件

1. adb logcat FregTest:i *:s是什么意思?logcat命令如何使用?

#

答:①:这是一条过滤指令。表示只显示标签为FregTest的日志,且日志的优先级要为info(信息)以上。
②adb logcat 命令格式 :
    adb logcat [选项] [过滤项]
选项记录如下:
-- "-s"选项 : 设置输出日志的标签, 只显示该标签的日志;
--"-f"选项 : 将日志输出到文件, 默认输出到标准输出流中, -f 参数执行不成功;
--"-r"选项 : 按照每千字节输出日志, 需要 -f 参数, 不过这个命令没有执行成功;
--"-n"选项 : 设置日志输出的最大数目, 需要 -r 参数, 这个执行 感觉 跟 adb logcat 效果一样;
--"-v"选项 : 设置日志的输出格式, 注意只能设置一项;
--"-c"选项 : 清空所有的日志缓存信息;
--"-d"选项 : 将缓存的日志输出到屏幕上, 并且不会阻塞;
--"-t"选项 : 输出最近的几行日志, 输出完退出, 不阻塞;
--"-g"选项 : 查看日志缓冲区信息;
--"-b"选项 : 加载一个日志缓冲区, 默认是 main, 下面详解;
--"-B"选项 : 以二进制形式输出日志;
过滤项为
-- V : Verbose (明细);
-- D : Debug (调试);
-- I : Info (信息);
-- W : Warn (警告);
-- E : Error (错误);
-- F: Fatal (严重错误);
-- S : Silent(Super all output) (最高的优先级, 可能不会记载东西);

3.Android源代码根本目录下/external目录用处?

答:/external目录主要存放的是一些开源的模组,包括蓝牙、AES加密、google应用库、防火墙等等,只要是由其他开发者完成的模块,都存放在这个目录下。

4. 为什么编译之后的文件存放在目录

答:Android在编译完成之后在根目录下生成一个out目录。
/out/target表示在目标机(ARM)上运行的内容。
../Product含义是此时编译的是针对产品的内容
../Generic目录是表示选定的产品还可生成其他目录,
../system目录是存放主要的文件系统的
../bin用来存放文件系统的二进制文件

AndroidBinder进程间通信系统-android学习之旅(86)的更多相关文章

  1. 我的Android学习之旅(转)

    去年大概在七月份的时候误打误撞接触了一阵子Android,之后由于工作时间比较忙,无暇顾及,九月份的时候自己空闲的时间比较多,公司相对来说加班情况没以前严重.开启了个人的Android学习之旅,初衷是 ...

  2. Android学习之旅(一)

    2017-02-27 今天开始,正式开启Android学习之旅,背景从事.Net平台开发快五年了,一直在用C#做Web开发. 前天选购了两本书:<Java 编程思想(第四版)>和<第 ...

  3. Intent启动系统组件(activity,service,BroadReceiver)-android学习之旅(四十九)

    android提供了统一的编程模型Intent来启动系统的组件,这样提供了松耦合性.是一种mvc的编程模式 $(function () { $('pre.prettyprint code').each ...

  4. Binder和SurfaceFlinger以及SystemServer介绍-android学习之旅(79)

    由于binder机制的存在,使得进程A可以访问进程B中的对象. Android系统Binder机制中的四个组件Client.Server.Service Manager和Binder驱动程序: 1. ...

  5. android的Binder通信机制java层浅谈-android学习之旅(88)

    1.Service Manager的Java代理对象 在Java层中,Service Manager的代理对象类型为ServiceManagerProxy.它继承并且实现了IServiceManage ...

  6. Android的启动过程分析(从进程和Framework的角度)-android学习之旅(98)

    Android的启动过程包含从Linux加载到home程序运行的过程,如下图所示: 1.linux内核: Android是基于Linux内核的系统平台.启动时,首先通过bootloader加载LInu ...

  7. 【Android学习之旅】1、Android入门介绍

    1.Android介绍 1.1 Android的系统架构 下面这张图展示了Android的系统架构: 图中可见,Android大致可以分为四层架构,五块区域: Linux内核层(Linux Kerne ...

  8. Android学习之旅:五子棋

    在学完了Android的基础之后,我开始尝试着写一些小项目练练手,同时进一步巩固自己的基础知识,而我选的的第一个项目就是做一个简单的人人对战的五子棋小游戏. 首先,我们要新建一个自定义控件类Panel ...

  9. Android摄像头照相机技术-android学习之旅(八)

    简介 Android SDK支持Android设备内置的照相机.从Android2.3开始支持多个摄像头(主要指前置摄像头和后置摄像头).通过照片相可以拍照和录像. 需要考虑的问题 是否支持照相机 快 ...

随机推荐

  1. springMVC源码分析--RequestToViewNameTranslator请求到视图名称的转换

    RequestToViewNameTranslator可以在处理器返回的View为空时使用它根据Request获取viewName.RequestToViewNameTranslator提供的实现类只 ...

  2. linux:cpu 每-CPU 的变量

    每-CPU 的变量 每-CPU 变量是一个有趣的 2.6 内核的特性. 当你创建一个每-CPU变量, 系统中每个处理器获得它自己的这个变量拷贝. 这个可能象一个想做的奇怪的事情, 但是它有自己的优点. ...

  3. MacOS获取辅助功能权限控制鼠标点击事件

    昨晚玩一个模拟经营的游戏,由于升级太慢我就不停的种树卖树来换取经验值.不过重复点击10几分钟后,实在受不了.网上本来准备找个鼠标自动点击的软件用用.结果没找到趁手的.如是自己写了个. 自己设置需要点击 ...

  4. iOS 滚动视图的复用问题解决方案

    LazyScroll是什么 LazyScrollView 继承自ScrollView,目标是解决异构(与TableView的同构对比)滚动视图的复用回收问题.它可以支持跨View层的复用,用易用方式来 ...

  5. C++ 虚函数表 单继承

    本文研究单继承情况下,c++对象的虚函数表的具体情况. 假设有两个类A,B, 其中B由A派生出来,A含有虚函数fun1,B含有虚函数fun2. 测试的代码如下: #include<iostrea ...

  6. main函数之后的调用

    main函数代表进程的主线程.程序开始执行时,系统为程序创建一个进程,main函数其实并不是首先被调用的函数,而是操作系统调用了C/C++运行期启动函数,该函数负责对C/C++ 运行期库进行初始化.它 ...

  7. 深入浅出如何解析xml文件---下篇

    在上篇博文中,小编主要介绍xml的两种解析方式,分别是dom4j和dom,今天这篇博文,小编主要来简单介绍一下xml的其她两种解析方式sax和jdom.  sax解析xml文件 sax,全称是Simp ...

  8. C++:如何删除string对象的末尾非数字字符

    功能实现: 现有一个string对象包含数字字符以及非数字字符,实现删除string对象的末尾非数字字符. 实例: 输入为"0 1 1 2 3    " 输出为"0 1 ...

  9. [Ubuntu] 14.04 关闭桌面

    一直在用Ubuntu的桌面来做调试环境,最近发现桌面会有崩溃的时候,占用资源也比较大,所以想把桌面关闭,只用command界面. 我的系统是Ubuntu14.04 Ctrl+Alt+F1 可以转到命令 ...

  10. Android Studio 不得不知的20大快捷键

    如何进入设置快捷键的界面: Android Studio -> References -> Keymap 使用的Keymaps为 Eclipse(Mac OS X)如下图所示: 1 展开和 ...