目录

前言及知识准备
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. ZooKeeper之(五)集群管理

    在一台机器上运营一个ZooKeeper实例,称之为单机(Standalone)模式.单机模式有个致命的缺陷,一旦唯一的实例挂了,依赖ZooKeeper的应用全得完蛋. 实际应用当中,一般都是采用集群模 ...

  2. 远程拷贝、查看端口、vim常见快捷键、查找替换命令、grep命令、查看存储空间的命令、chkconfig命令、系统自动启动级别、主机名配置、IP地址配置、域名映射、防火墙设置

    2.1.远程拷贝 (将/export/servers/hadoop上的文件拷贝到bigdate@192.168.1.1:/export/servers/ ) scp –r /export/server ...

  3. Python Tkinter小试

    前两天看到一篇关于Python使用Tkinter 的博文,写的很好.就拿来研究了一下,改了改.现分享如下: 参考 代码 # coding:utf8 # python2.73 winxp ''''' 天 ...

  4. 给定一个实数数组,按序排列(从小到大),从数组从找出若干个数,使得这若干个数的和与M最为接近,描述一个算法,并给出算法的复杂度。

    有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M. 需要选出若干个x,使这几个x的和与 M 最接近. 请描述实现算法,并指出算法复杂度. #define M 8 ...

  5. Linux动态频率调节系统CPUFreq之一:概述

    随着技术的发展,我们对CPU的处理能力提出了越来越高的需求,芯片厂家也对制造工艺不断地提升.现在的主流PC处理器的主频已经在3GHz左右,就算是智能手机的处理器也已经可以工作在1.5GHz以上,可是我 ...

  6. actionbar详解(二)

    经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对较为深刻的理解了.唯一欠缺的是,前面我们都只是学习了理论知识而已,虽然知识点已经掌握了,但是真正投入到项目实战当中时会不会掉链子还很 ...

  7. ProgressBar的简单使用

    当我们的应用在进行耗时操作时,显示一个进度条呈现给用户,让用户知道当前进度是一个很好的体验,接下来我们就来简单了解下ProgressBar(本文主要针对初学者,大神可以绕开啦),先看效果图: 进度条P ...

  8. android viewpager切换到最后一页时,跳转至其他activity

    许许多多的qpp,在启动时会显示一些帮助页或者产品介绍什么的,通常滑动到最后一页时会有一个开始体验的按钮,用来跳转到app的主activity上,但是如果没有? 可以通过如下方法实现: 1.为View ...

  9. 早期Swift中Cocos2D初始化代码的重构

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在早期的Swift中在子类里只能调用超类的design ...

  10. linux C++多线程操作文件&输出加锁

    下述demo将指定目录下文件存入vector,然后一分为二交给两个线程(threadTask1,threadTask2)去分别处理,对输出函数printDirent加锁防止紊乱. #include & ...