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

  • 相关阅读:
    走进__proto__属性,看ie是否支持它,谁又来给他归宿
    如何安装zip格式的MySQL
    博客初心源于前端攻城狮
    Day 1: How to install jedi/codeintel plugin for sublime on Linux
    关于拓扑排序的一些想法
    POJ1061 青蛙的约会 __一维世界的爱情
    缩步查找法——一种新的查找算法
    HDU3371 Connect the Cities
    HDU1598 find the most comfortable road
    codeforces 349 div2.c
  • 原文地址:https://www.cnblogs.com/yemeishu/p/2796677.html
Copyright © 2011-2022 走看看