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。

  

  JNIJava 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源码了。

posted @ 2012-11-30 18:24  叶梅树  阅读(2154)  评论(0编辑  收藏  举报