Android源码学习之如何创建使用JNI
在Android平台下,JNI就是一座Java世界和Native世界之间的桥梁。因此要学好Android的源码,首先就要懂得什么是JNI,如何使用JNI。
JNI是Java Native Interface的缩写。从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。下面通过实现简单的加法函数,来手动实现如何使用JNI。
JNI(Java Native Interface)的实现步骤:
- 编写带有native声明的方法的java类。
- 使用javac命令编译所编写的java类。
- 使用javah -jni java类名生成扩展名为h的头文件。
- 使用C/C++(或者其他编程想语言)实现本地方法。
- 将C/C++编写的文件生成动态连接库。
1. 编写Java程序。
public class NativeTest { public static void main(String[] args) { NativeTest aTest = new NativeTest(); int i0 = Integer.valueOf(args[0]).intValue(); int i1 = Integer.valueOf(args[1]).intValue(); double d = aTest.Add(i0, i1); System.out.println("i0 + i1 = " + d); } public native double Add(int i, int j); static { System.loadLibrary("NativeTest"); } }
在Java的文件中,首先声明一个Native方法public native double Add(int i, int j);
注:在该方法中不包含任何代码(具体代码在C++语言或者其他语言中实现,并且作为DLL提供)。
为了确保Java虚拟机在首次使用该类的时候将DLL装载到内存,需要在包含这个Native方法的类中使用静态初始化程序块。如:
static { //装载动态链接库 System.loadLibrary("NativeTest"); }
2. 在doc下,使用javac NativeTest.java 命令编译java类文件。
3. 在同样的文件目录下,使用javah -jni NativeTest 命令生成NativeTest.h文件,生成的文件内容如下所示。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class NativeTest */ #ifndef _Included_NativeTest #define _Included_NativeTest #ifdef __cplusplus extern "C" { #endif /* * Class: NativeTest * Method: Add * Signature: (II)D */ JNIEXPORT jdouble JNICALL Java_NativeTest_Add (JNIEnv *, jobject, jint, jint); #ifdef __cplusplus } #endif #endif
4. 使用C/C++(或者其他编程想语言)实现NativeTest.h头文件的方法,也就是java文件中没实现的需要通过动态链接库调用的Add方法。其中在相同的目录中建立NatieTest.cpp实现文件,程序为:
#include "NativeTest.h" #include <math.h> JNIEXPORT jdouble JNICALL Java_NativeTest_Add (JNIEnv *env, jobject obj, jint i, jint j) { return i + j; }
实现Add函数。
5. 使用vc++ 的cl命令进行编译cpp文件,生成dll库文件,供java调用实现。
由于我的电脑安装的vs2012,所以可以通过VS2012开发人员命令提示,输入cl命令,编译。
首先cd到NativeTest程序目录下,输入:cl -I "C:\Program Files\Java\jdk1.7.0_07\include" -I "C:\Program Files\Java\jdk1.7.0_07\include\win32" -LD NativeTest.c -FeNativeTest.dll
其中C:\Program Files\Java\jdk1.7.0_07\include是我本地安装的jdk路径,输入时一定要加“”。最后会生成NativeTest.exp NativeTest.dll等文件。
6. 最后运行java程序,java NativeTest 1 2 结果如下所示:
这就表示我们手动建立的JNI成功。
对JNI有了初步的了解,下一步就可以更好的理解Android源码了。