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)的更多相关文章

  1. Android的fuzz测试技术之符号执行浅谈-android学习之旅(82)

    简单的漏洞越来越少,需要改进目前的方法 : 通过符号执行,得出执行路径,然后在进行fuzzy是较为有效的方法之一 1)为待测单元自动地生成可到达的测试数据,即提高测试目标的覆盖率 2)根据特定的漏洞模 ...

  2. 从AIDL开始谈Android进程间Binder通信机制

    转自: http://tech.cnnetsec.com/585.html 本文首先概述了Android的进程间通信的Binder机制,然后结合一个AIDL的例子,对Binder机制进行了解析. 概述 ...

  3. Binder通信机制介绍

    1.Binder通信机制介绍 这篇文章会先对比Binder机制与Linux的通信机制的差别,了解为什么Android会另起炉灶,采用Binder.接着,会根据 Binder的机制,去理解什么是Serv ...

  4. 浅谈android代码保护技术_ 加固

    浅谈android代码保护技术_加固 导语 我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk,结果被人反编译了,那心情真心不舒服.虽然我们混淆,做到native层,但 ...

  5. 浅谈Android应用保护(一):Android应用逆向的基本方法

    对于未进行保护的Android应用,有很多方法和思路对其进行逆向分析和攻击.使用一些基本的方法,就可以打破对应用安全非常重要的机密性和完整性,实现获取其内部代码.数据,修改其代码逻辑和机制等操作.这篇 ...

  6. 浅谈Android编码规范及命名规范

    前言: 目前工作负责两个医疗APP项目的开发,同时使用LeanCloud进行云端配合开发,完全单挑. 现大框架已经完成,正在进行细节模块上的开发 抽空总结一下Android项目的开发规范:1.编码规范 ...

  7. 【转】Android Canvas的save(),saveLayer()和restore()浅谈

    Android Canvas的save(),saveLayer()和restore()浅谈 时间:2014-12-04 19:35:22      阅读:1445      评论:0      收藏: ...

  8. 浅谈Android应用性能之内存

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 文/ jaunty [博主导读]在Android开发中,不免会遇到许多OOM现象,一方面可能是由于开 ...

  9. 浅谈Android Studio3.0更新之路(遇坑必入)

    >可以参考官网设置-> 1 2 >> Fantasy_Lin_网友评论原文地址是:简书24K纯帅豆写的我也更新一下出处[删除]Fa 转自脚本之家 浅谈Android Studi ...

随机推荐

  1. Git 直接推送到生产服务器

    假设路径为/project/path/ 设定git仓库可以直接被远程推送(需要较新的git版本,比如2.7) cd /project/path git config receive.denyCurre ...

  2. 从Dynamics CRM2011到Dynamics CRM2016的升级之路

    CRM的产品更新特别快,特别是最近的几个版本,很多客户依旧停留在2011甚至是4.0,也经常会听到有人问2011能不能升级至最新版,2013能不能升级至最新版,本文将简单演示下从2011升级到2016 ...

  3. shiro salt

    1.1 散列算法 散列算法一般用于生成一段文本的摘要信息,散列算法不可逆,将内容可以生成摘要,无法将摘要转成原始内容.散列算法常用于对密码进行散列,常用的散列算法有MD5.SHA.分享牛系列,分享牛专 ...

  4. Docker与容器

    Docker介绍 1. Docker 主要解决什么问题 Docker 对外宣称的是Build.Ship 和Run,Docker 要解决的核心问题就是快速地干这三件事情.它通过将运行环境和应用程序打包到 ...

  5. 关于bootstrap在IE8下不能支持自适应的问题

    说到这个问题,我就想吐槽下IE了,开发这么多版本,每个版本都有一些这样那样的问题不支持,别的正常的浏览器咋都能支持呢?真是垃圾浏览器!!!! 说归说,但是IE现在用的人多啊,怎么办?这个问题还是得解决 ...

  6. 设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误

    我们做 iOS 程序开发时经常用遇到 EXC_BAD_ACCESS 错误导致 Crash,出现这种错误时一般 Xcode 不会给我们太多的信息来定位错误来源,只是在应用 Delegate 上留下像 T ...

  7. Android Multimedia框架总结(六)C++中MediaPlayer的C/S架构

    转载请把头部出处链接和尾部二维码一起转载,本文出自: http://blog.csdn.net/hejjunlin/article/details/52435789 前面几节中,都是通过java层调用 ...

  8. 给定整数a1、a2、a3、...、an,判断是否可以从中选出若干个数,使得它们的和等于k(k任意给定,且满足-10^8 <= k <= 10^8)。

    给定整数a1.a2.a3.....an,判断是否可以从中选出若干个数,使得它们的和等于k(k任意给定,且满足-10^8 <= k <= 10^8). 分析:此题相对于本节"寻找满 ...

  9. Android布局中ScrollView与ListView的冲突的最简单方法

    看到网上流行的一种使用方法是: public class Utility { public static void setListViewHeightBasedOnChildren(ListView ...

  10. 【java虚拟机系列】从java虚拟机字节码执行引擎的执行过程来彻底理解java的多态性

    我们知道面向对象语言的三大特点之一就是多态性,而java作为一种面向对象的语言,自然也满足多态性,我们也知道java中的多态包括重载与重写,我们也知道在C++中动态多态是通过虚函数来实现的,而虚函数是 ...