android的Binder通信机制java层浅谈-android学习之旅(88)
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层中相对应的服务。
android的Binder通信机制java层浅谈-android学习之旅(88)的更多相关文章
- Android的fuzz测试技术之符号执行浅谈-android学习之旅(82)
简单的漏洞越来越少,需要改进目前的方法 : 通过符号执行,得出执行路径,然后在进行fuzzy是较为有效的方法之一 1)为待测单元自动地生成可到达的测试数据,即提高测试目标的覆盖率 2)根据特定的漏洞模 ...
- 从AIDL开始谈Android进程间Binder通信机制
转自: http://tech.cnnetsec.com/585.html 本文首先概述了Android的进程间通信的Binder机制,然后结合一个AIDL的例子,对Binder机制进行了解析. 概述 ...
- Binder通信机制介绍
1.Binder通信机制介绍 这篇文章会先对比Binder机制与Linux的通信机制的差别,了解为什么Android会另起炉灶,采用Binder.接着,会根据 Binder的机制,去理解什么是Serv ...
- 浅谈android代码保护技术_ 加固
浅谈android代码保护技术_加固 导语 我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk,结果被人反编译了,那心情真心不舒服.虽然我们混淆,做到native层,但 ...
- 浅谈Android应用保护(一):Android应用逆向的基本方法
对于未进行保护的Android应用,有很多方法和思路对其进行逆向分析和攻击.使用一些基本的方法,就可以打破对应用安全非常重要的机密性和完整性,实现获取其内部代码.数据,修改其代码逻辑和机制等操作.这篇 ...
- 浅谈Android编码规范及命名规范
前言: 目前工作负责两个医疗APP项目的开发,同时使用LeanCloud进行云端配合开发,完全单挑. 现大框架已经完成,正在进行细节模块上的开发 抽空总结一下Android项目的开发规范:1.编码规范 ...
- 【转】Android Canvas的save(),saveLayer()和restore()浅谈
Android Canvas的save(),saveLayer()和restore()浅谈 时间:2014-12-04 19:35:22 阅读:1445 评论:0 收藏: ...
- 浅谈Android应用性能之内存
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 文/ jaunty [博主导读]在Android开发中,不免会遇到许多OOM现象,一方面可能是由于开 ...
- 浅谈Android Studio3.0更新之路(遇坑必入)
>可以参考官网设置-> 1 2 >> Fantasy_Lin_网友评论原文地址是:简书24K纯帅豆写的我也更新一下出处[删除]Fa 转自脚本之家 浅谈Android Studi ...
随机推荐
- Sybase identity 字段
1.identity Oracle, DB2, pgSQL中都有sequence的概念,这个概念比Identity先进很多,在Sybase中没有Sequence对象,与之相对应的是Identity 2 ...
- Android Support库——support annotations
Android Support库是官方出的支持扩展库,包含了丰富的组件.工具类等,通过在Android SDK Manager中勾选以下两项来获取到. 其中,Android Support Libra ...
- 初始化nodejs+webpack+vuejs
安装nodejs 4.x 参考 curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - sudo apt-get install ...
- J2EE进阶(十七)Hibernate中常用的HQL查询方法(getHibernateTemplate())
J2EE进阶(十七)Hibernate中常用的HQL查询方法(getHibernateTemplate()) 当我们使用Hibernate进行数据的CRUD操作时,利用模版进行操作不失为一种方法. ...
- 剑指Offer——“你最大的缺点是什么”回答技巧及范例
剑指Offer--"你最大的缺点是什么"回答技巧及范例 问题分析:认识自己的缺点是一个巨大的优点, 当HR问到你缺点的时候, 你的机会来了, 请快展示你的自知之明吧!你想把优点 ...
- 给定一数组,输出满足2a=b(a,b代表数组中的数)的数对,要求时间复杂度尽量低。
//时间复杂度O(n),空间复杂度O(n) void findSequence(int* arr, int len) { int* hashtable = new int[RANGE]; memset ...
- 有一台机器,上面有m个储存空间。然后有n个请求,第i个请求计算时需要占 R[i]个空间,储存计算结果则需要占据O[i]个空间(据O[i]个空间(其中O[i]<R[i])。问怎么安排这n个请求的顺序,使
有一台机器,上面有m个储存空间.然后有n个请求,第i个请求计算时需要占 R[i]个空间,储存计算结果则需要占据O[i]个空间(据O[i]个空间(其中O[i]<R[i]).问怎么安排这n个请求的顺 ...
- 供应商导入的API补充(详解EBS接口开发之供应商导入)
--供应商 --创建 AP_VENDOR_PUB_PKG.Create_Vendor ( p_api_version IN NUMBER, p_init_msg_list IN VARCHAR2 := ...
- 深入了解UIViewController控制器与对应的View类的详解
ViewController是iOS开发中MVC模式中的C(视图控制器),ViewController是view的controller,ViewController的职责主要包括管理内部各个view的 ...
- 【Netty源码学习】DefaultChannelPipeline(三)
上一篇博客中[Netty源码学习]ChannelPipeline(二)我们介绍了接口ChannelPipeline的提供的方法,接下来我们分析一下其实现类DefaultChannelPipeline具 ...