文档章节

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

fengsehng
 fengsehng
发布于 2016/11/09 09:07
字数 2029
阅读 8
收藏 0

1.Service Manager的Java代理对象

在Java层中,Service Manager的代理对象类型为ServiceManagerProxy。它继承并且实现了IServiceManager接口,其中四个成员函数和一个变量如下:
getService、checkService:获取Java服务代理对象
addService:注册Java服务
listService:获取已经注册的java服务表mRemote:类型为Ibinder,指向了一个BinderProxy对象。这个对象用来描述Java服务代理对象,内部的成员变量mObject,指向c++层中的一个Binder代理对象。Java服务代理和c++层中的服务代理由此联系起来。
在Java层中,Service Manager的代理对象由Service Manager类创建。
其成员函数getIServiceManager,作用就是用来获取Service Manager的Java远程接口了,而这个函数又是通过ServiceManagerNative类的成员方法asInterface来获取Service Manager的Java远程接口的。
这里写图片描述
从上面代码可看出在调用asInterface函数之前,首先要通过getContextObject函数来获得一个BinderProxy对象。
getContextObject是一个JNI方法:
这里写图片描述
第3行调用函数获得一个句柄为NULL的Binder代理对象。第4行使用函数javaObjectForIBinde为这个对象创建一个Java服务代理对象(BinderProxy)。
第3行调用函数获得一个句柄为NULL的Binder代理对象。第4行使用函数

javaObjectForIBinde为这个对象创建一个Java服务代理对象(BinderProxy)。

这里写图片描述
这里传进来的参数是一个BpBinder的指针,而BpBinder::checkSubclass继承于父类IBinder::checkSubclass,它什么也不做就返回false。于是直接向下执行:

会创建一个Java层的BinderProxy对象

这里写图片描述
17行中,由于这个BpBinder对象是第一创建,它里面什么对象也没有,因此,这里返回的object为NULL。继续执行

最后的代码如下:

这里写图片描述

小结:整个的过程就是在Java层,我们拥有了一个Service Manager远程接口ServiceManagerProxy,而这个ServiceManagerProxy对象在JNI层有一个句柄值为0的BpBinder对象与之通过gBinderProxyOffsets关联起来。这样获取Service Manager的Java远程接口的过程就完成了。

2Java服务接口的定义

在实现Java服务之前,必须要定义这个Java服务接口。在Android中通过AIDL语言来定义Java服务接口。
首先,以一个硬件访问服务为例,其aidl文件如下:
setVal设置变量
getVal获取变量
文件编译后会生成一个IFregService.java文件
这里写图片描述

IFregService.java文件展开如下:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

总结:aidl文件编译之后,就是根据IFregService接口的定义生成相应的Stub和Proxy类,即实现这个FregService的Server必须继承于这里的IFregService.Stub类,而这个FregService的远程接口就是这里的IFregService.Stub.Proxy对象获得的IFregService接口。

3Java服务接口的启动

Java服务和binder服务一样,同样需要将自己注册到Service Manager中,但是由于system和Android进程启动的时候都会在内部启动一个线程池,所以运行在里面的Java服务启动时,只需要注册服务,不需要添加线程池。
服务FregService是从IFregService.Stub类继承来的,是一个实现了IFregService接口的Java服务

定义如下

这里写图片描述
第8行首先创建一个服务FregService,然后接着调用ServiceManager类的静态成员函数addService来注册。
首先分析创建过程:new FregService
由于硬件访问服务FregService继承了IFregService.Stub类,这个类继承了Binder类,因此最终创建服务时会调用Binder类的构造函数。
构造函数调用了成员函数init来执行初始化工作,init是一个JNI方法。
这里写图片描述

小结:注册Java服务时,并不是真的将Java服务注册到Service Manager中,而是将它对应的一个类型为JavaBBinder的本地对象注册到Service Manager中。当这个JavaBBinder类型的本地对象收到来自client进程的进程间通信请求时,他就需要将这个请求发送给Java服务来处理。

4Java服务代理对象的获取

ava服务在注册到Service Manager之后,Android应用程序就可以通过它来获取一个Java服务的代理对象,通过代理对象,就可以使用相应的Java服务了。
因此,客户端想要使用服务,首先要获取Java服务的代理对象,下面分析流程:

客户端中代码如下:

这里写图片描述
在第7行①通过ServiceManager类的静态函数getService获取名称为”freg”的Java服务代理对象;②使用IFregService.Stub类的函数asInterface将其转化为实现了服务接口的代理对象。

小结:经过两个函数的封装,getService函数相当于下面语句这就是我们想要获得的Java服务代理对象了。再获取了Java代理对象后,就可以调用服务了。Binder机制在提供Java接口时使用了JNI方法封装c++接口,使用AIDL语言来完成服务的定义,使用全局数据结构将Java服务接口中的各种对象和对应在c++层中的各个对象关联起来,从而使Android应用可以通过Java语言使用Binder进程间通信。

5实例

Service代码如下:

这里写图片描述

客户端的activity代码如下:

这里写图片描述

aidl文件代码如下:

这里写图片描述

aidl对应的java文件内容为:

这里写图片描述
这里写图片描述
这里写图片描述

运行截图

这里写图片描述

普通服务 和系统服务是有些区别的:

①服务启动和注册:系统服务是需要更改Android源码,将服务添加至systemserver中,并且随开机启动;此次实例是将服务编译好之后把相应的包存放在客户端功能内,当做一个数据文件来访问的。
②调用:调用系统服务客户端需要一个service manager的代理对象,靠它寻找服务的代理对象,并且完成服务;而此实例则是在客户端内使用包含了这个服务的包以及相应的接口,是对系统服务调用的一个简化。

Binder机制在java层和C++层的实现的相同点和不同点?

相同点:①这两层的Binder机制结构是相同的。Java层的Binder机制实际上是对c++层次进行了一个封装,使用JNI方法,使得Java代码可以调用c++层中相应的函数。
②仅从使用方式来看两个层是相同的。都是 首先需要一个Service Manager,随后定义相关的服务,之后把服务注册到Service Manager中;客户端在使用服务时,首先获得Service Manager的代理对象,之后从中找到相关的服务代理对象,在从这个服务代理对象中找到相关服务函数,调用函数完成Binder通信功能。
不同点:①数据结构:Java层想使用Binder机制就必须使用JNI方法调用C++层中的相应的对象,因此在Java层和c++层中要记录相对应的对象的地址,把两者关联起来,在Java层中就可以完成c++层中的功能
②服务的定义:c++层运行在系统底层,因此服务的定义可以直接写在头文件中,随系统运行。但是Java服务需要使用AIDL语言来定义,才能时Java服务接口有Binder通信能力。
③服务的启动:c++层的服务需要由服务端自己分配Binder线程池,而Java层的服务随着system启动,不需要自己分配。
④服务的调用:c++层:首先获得service manager的代理对象,通过它获得一个服务的代理对象,通过服务代理对象完成通信。
Java:首先获得Java层的service manager的代理对象,再通过JNI方法获得c++层中Binder代理对象,将他封装成Java服务的代理对象,返回给调用者,在使用函数的时候通过JNI方法使用c++层的Binder机制,通过Binder机制寻找Java层中相对应的服务。

本文转载自:http://blog.csdn.net/lpjishu/article/details/49942919

共有 人打赏支持
fengsehng
粉丝 4
博文 284
码字总数 214494
作品 0
朝阳
程序员
私信 提问
Android 源码分析之旅1--系统架构与分析方法、工具

《Android 源码分析之旅》目录 apefwkall.png 《Android 源码分析之旅》的全部目录将作如下安排: 第1章节——本篇文章,将介绍一些基本的概念、方法、工具。 第2章节——着重介绍Binder IP...

猴亮屏
2017/10/19
0
0
Android系统的Binder机制之三——服务代理对象(2)

文《Android系统的Binder机制之二——服务代理对象(1)》我们学习了进程的C/C++层面的服务代理对象BpBinder,和Binder底层处理方式。本文我们将深入分析一下在进程的Java层面服务代理对象的...

垂盆草
2012/08/04
0
0
Android应用开发以及设计思想深度剖析(3)

特别声明:本系列文章LiAnLab.org著作权所有,转载请注明出处。作者系LiAnLab.org资深Android技术顾问吴赫老师。 我们接下来从安全性,性能,功能,可移植性的角度分别分析Android系统为应用...

21cnbao
2012/09/14
0
0
[深入理解Android卷二 全文-第二章]深入理解Java Binder和MessageQueue

由于《深入理解Android 卷一》和《深入理解Android卷二》不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在OSC博客中全文转发这两本书的全部内容 第2章 深入理解Java Bind...

邓凡平
2015/08/03
0
1
Android IPC进程间通讯机制

一.Linux系统进程间通信有哪些方式? 1.socket; 2.name pipe命名管道; 3.message queue消息队列; 4.singal信号量; 5.share memory共享内存; 二.Java系统的通信方式是什么? 1.socket; ...

Simpleness
2012/06/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Flink-数据流编程模型

1、抽象等级 Flink提供了不同级别的抽象来开发流/批处理应用程序。 1) 低层级的抽象 最低层次的抽象仅仅提供有状态流。它通过Process函数嵌入到DataStream API中。它允许用户自由地处理来自一...

liwei2000
23分钟前
1
0
Java开发Swing实战JFrame和JTabbedPane容器的用法详细解析

概述: 项目是一个桌面程序,涉及标签和按钮组件、布局管理器组件、面板组件、列表框和下拉框组件等组件,以及Swing事件处理机制。 下面先从最基础的界面开始。 /** * @author: lishuai * @...

金铭鼎IT教育
28分钟前
9
0
flask 之旅

环境 为了正确地跑起来,你的应用需要依赖许多不同的软件。 就算是再怎么否认这一点的人,也无法否认至少需要依赖Flask本身。 你的应用的运行环境,在当你想要让它跑起来时,是至关重要的。 ...

hblt-j
29分钟前
6
0
easyui的上传文件

记录一下自己亲手操刀easyui的心得:不用不知道,一用就问题多,网上查资料,有用的真的太少了 ——————————————————正文 FileBox,还是不错的讲真,至少我去自己写就gaga了...

anlve
30分钟前
4
0
如何做好SQLite 使用质量检测,让事故消灭在摇篮里

本文由云+社区发表 SQLite 在移动端开发中广泛使用,其使用质量直接影响到产品的体验。 常见的 SQLite 质量监控一般都是依赖上线后反馈的机制,比如耗时监控或者用户反馈。这种方式问题是: ...

腾讯云加社区
32分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部