android的Binder通信机制java层浅谈

原创 2015年11月20日 09:28:14

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层中相对应的服务。

                        我的文章首发于公众号
                        互联网学术(IT-paper)
                        了解更多,互请扫码上车

扫码上车

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

在前面几篇文章中,我们详细介绍了Android系统进程间通信机制Binder的原理,并且深入分析了系统提供的Binder运行库和驱动程序的源代码。细心的读者会发现,这几篇文章分析的Binder接口都是...

安卓高手之路之java层Binder

很多人一提到Binder就说代理模式,人云亦云的多,能理解精髓的少。 本篇文章就从设计角度分析一下java层BInder的设计目标,以及设计思路,设计缺陷,从而驾驭它。      对于【邦德儿】的理...

android (八)Binder浅谈

在这里写下对binder的理解,说到Binder间进程通信,Linux那么多进程间通信工具为何引入了Binder。大概原因有两点: 1、为了提高通信的效率。 2、为了方便开发者,让进程间通信和RPC(...

彻底理解 Android Binder 通信架构

roid 6.0的源码剖析, 本文深度剖析Binder IPC过程, 这绝对是一篇匠心巨作,从Java framework到Native,再到Linux Kernel,带你全程看Binder通信过程....

binder通信实例之java客户端与c++服务端

待续

Android Binder通信机制学习

binder驱动和通信库是binder的核心,驱动是用c语言编写的,通信库是c++写的,应用程序通过jni和底层的库产生联系,建议研究binder的读者先读完和这两本书做好研究准备,有时间的也可以学学...

Java层Binder机制详解

这篇文章是阅读《Android 内核剖析》一书的笔记,现在写下来希望能加深自己的理解,如果理解错误,希望各位朋友能指出来。     Binder是一种基于C/S的架构,主要包括四个部分:服务端(S...

理解Android Binder机制(3/3):Java层

本文是Android Binder机制解析的第三篇,也是最后一篇文章。本文会讲解Binder Framework Java部分的逻辑。 Binder机制分析的前面两篇文章,请移步这里: 理...

Android7.0 Binder通信(4) Java层中的Binder

之前博客分析Binder机制时,集中分析的是Native层Binder的架构,现在来分析一下Java层Binder的架构。...

[深入理解Android卷二 全文-第二章]深入理解Java Binder和MessageQueue

由于《深入理解Android 卷一》和《深入理解Android卷二》不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容 第2章  深入理解Java...
  • Innost
  • Innost
  • 2015年08月03日 10:39
  • 5174
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android的Binder通信机制java层浅谈
举报原因:
原因补充:

(最多只允许输入30个字)