Android FrameWork 由Java层与C/C++层组成,JNI就是将这两层联系起来的媒介;
在实际的Android开发中,使用SDK开发Java程序;
而对于性能要求高的,如图形处理或信号处理,需要使用NDK开发基于C/C++的本地库,再由JNI连接本地库和应用程序。
使用JNI的三种情况:
1、注重处理速度;
2、硬件控制:在搭载Android的设备上安装Android FrameWork不支持的硬件时,需使用C语言实现设备的驱动程序,以便对设备进行控制;
3、既有C/C++代码的复用。
以GPS为例,在获取GPS信息时,先调用FrameWork中的Location Manager提供的一套控制硬件的Java API,再调用GPS库连接到C/C++写的设备驱动上,
JNI就是将硬件设备驱动映射成Java API.
在JAVA中调用C函数:
1、编写编译java代码
2、javah 生成C语言头文件
3、根据头文件中的函数原型,实现JNI本地函数
4、生成C共享库(使用Visual C++)
5、运行java程序
class HelloJNI
{
//本地方法声明
native void printHello();
//加载库,windows下是hellojni.dll运行库,linux下是libhellojni.so
static { System.loadLibrary("hellojni");}
public static void main(String args[ ])
{
HelloJNI myJNI=new HelloJNI();
myJNI.printHello();
}
}
直接调用时,报UnsatisfiedLinkError: 使用javah工具(javah <java类名称>),在当前目录下生成包含函数原型的C/C++头文件。
在头文件中,可能有JNIEXPORT,JNICALL这样的宏定义,以及jobject这样带j的java本地类型。
在C中调用Java端代码:
1、创建java对象
2、访问类的静态成员域
3、访问类的静态方法
4、访问成员变量
5、访问Java对象的方法
直接注册JNI本地函数:
JNI机制提供了RegisterNatives()方法,程序员若在JNI_OnLoad()函数内调用RegisterNatives()方法将JNI本地函数与Java类的本地方法直接映射到一起,
则Java虚拟机就不必进行映射处理,这会极大提高运行速度。