您的位置:华清远见教育科技集团 >> Android资料 >> Android Java JNI机制详解  
 
Android Java JNI机制详解
分享到:

在Android中,为了完成上层应用和底层服务之间的相互调用,根据请求的服务不同,交互过程主要有3种类型:直接调用、通过原生服务调用、通过原生守护进程调用。考虑到上层的应用一般是基于Java实现的,而底层服务则是基于C/C++实现的,为了完成跨语言的交互,就需要用到Java JNI机制。

1. Java JNI原生接口

考虑到底层的Linux内核和中间层面的原生服务都是利用C/C++来写的,为了使应用程序能够访问到底层的原生服务和设备,就必须考虑Java和C/C++,甚至汇编语言间的互操作性。在Android中,Java和其他语言的交互是利用Java JNI机制来完成的。

自Java 1.1起,Java JNI(Java Native Interface)标准就已经是Java的一部分,JNI允许Java与其他语言编写的代码进行交互。

Java通过Java JNI调用本地方法,而本地方法是以共享库(*.so)文件的形式存放的,通过调用本地库文件的内部方法,使Java可以实现和本地机器的紧密联系,调用系统级的各接口方法。

在Android中,通过JNIEnv,使得C代码也能调用Java提供的服务,这方面的一个重要实例为IBinder通信。

但需要注意的是,利用C/C++等完成的底层代码的安全性较弱,无法防止开发者利用无效的指针来改写内存,这会导致虚拟机安全性的削弱。

在Android中,原生接口主要位于frameworks\base\core\jni \AndroidRuntime.cpp文件中。利用Java JNI注册原生接口的方法为:

/*static*/ int AndroidRuntime::registerNativeMethods(JNIEnv* env,
        const char* className, const JNINativeMethod* gMethods, int numMethods)
    {
        return jniRegisterNativeMethods(env, className, gMethods, numMethods);
    }

2. 直接调用

在直接调用模式中,上层应用通过IBinder机制与框架层的服务直接通信,框架层服务通过Java JNI动态加载相关的共享库,完成服务。

如图1-1所示为上层应用调用硬件抽象层(HAL,Hardware Abstraction Layer)提供的实时服务时的调用层次说明。需要说明的是,HAL的出现更多的是为底层提供封装,保护平台厂商和第三方厂商的利益。


图1-1 实时服务调用层次说明

如图1-2所示为智能手机中常见的位置服务的调用层次说明,上层的导航应用和其他的位置应用在获取底层的GPS服务时,首先调用位置管理器服务(Location Manager Service),然后通过Java JNI终调用libgps.so共享库。


图1-2 位置服务调用层次

3. 原生服务调用

在原生服务调用模式中,由于应用本身更加复杂,应用的抽象实现会放置在原生层,当上层应用调用底层的服务时,首选会通过Java JNI调用应用本身的原生接口,然后通过IPC通信与其他的原生服务进行交互。如图1-3所示为媒体播放应用的调用层次关系。

在多媒体应用中,这是常用的交互方式。


图1-3 原生服务

4.原生守护进程调用

在原生守护进程调用模式中,调用的原生服务通常是后台的守护进程,在这种模式中,上层应用会首先通过Java JNI和应用本身的原生接口通信,然后通过套接字或者IPC和守护进程通信。如图1-4所示为通话应用的调用层次关系。


图1-4 原生守护进程调用

 更多相关文章

·Android IBinder通信机制
·Android ONC RPC远程调用
·Dalvik虚拟机原生方法的注册
·Android Dalvik虚拟机启动
·Android服务管理器守护进程