zoukankan      html  css  js  c++  java
  • 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源码了。

  • 相关阅读:
    NYOJ 625 笨蛋的难题(二)
    NYOJ 102 次方求模
    ZJU Least Common Multiple
    ZJUOJ 1073 Round and Round We Go
    NYOJ 709 异形卵
    HDU 1279 验证角谷猜想
    BNUOJ 1015 信息战(一)——加密程序
    HDU 1202 The calculation of GPA
    "蓝桥杯“基础练习:字母图形
    "蓝桥杯“基础练习:数列特征
  • 原文地址:https://www.cnblogs.com/yemeishu/p/2796677.html
Copyright © 2011-2022 走看看