Android JNI基础简介

简介:    

    JNI的全称就是Java Native Interface,Java本地接口。

    作用:使得Java 与 本地其他类型语言(如C、C++)交互

    注意:JNI开发前提是要引入jni.h头文件,这个文件Android NDK目录下面

    示例: #include<jni.h>

  • 通过javac和javah编译出一个your_jni.h文件默认是包含#include<jni.h>的。所以在实现your_jni.h文件中的方法时只需要#include<your_jni.h>即可,无需在重复#include<jni.h>。
  • 若直接定义c/c++文件,需要#include<jni.h>。

一、NDK环境配置

1、现在NDK版本配置环境变量



2、AndroidStudio配置NDK路径

在local.properties文件中配置路径


3、在app build.gradel中添加ndk节点

defaultConfig {

.......

 ndk{
            //模块名称,编译后的.so库文件名称
            moduleName "HelloJni"
            //使用stl标准库(默认情况下JNI中无法使用STL标准库)
            stl "stlport_static"
            //log 表示加入Android的调试日志,只要导入#include<android/log.h>
            //就可以使用_android_log_print方法打印日志到logcat中
            ldLibs "log"
            //编译生成支持对应cpu类型的so库
            abiFilters "armeabi-v7a", "x86"
        }

}

二、实现JNI  

    配置好NDK环境后,下面开始编写c/c++代码。

1、先定义Java 调用的native方法

public class NativeJNIMethod {
    public static native String getNativieString();

    public static native int add(int a, int b);
}

2、通过javac和javah命令生成对应.h文件

    MApplication\app\src\main\java\com\example\mapplication\jniutil>javac NativeJNIMethod.java

    MApplication\app\src\main\java>javah -jni com.example.mapplication.jniutil.NativeJNIMethod

    命令执行后会生成一个class文件和.h文件分别生成在上面执行命令的对应目录下面。

3、在java目录下面新建jni目录

    新建jni后将上面的.h文件拷贝到该目录下面,然后在jni目录下新建c或c++文件实现.h头文件中的方法。这里的.h文件相当于一种定义方法的接口。


    新建c/c++文件实现.h中定义的方法


c++文件内容:

#include<com_example_mapplication_jniutil_NativeJNIMethod.h>

/*
 * Class:     com_example_mapplication_jniutil_NativeJNIMethod
 * Method:    getNativieString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_mapplication_jniutil_NativeJNIMethod_getNativieString
  (JNIEnv *env, jclass type){
    return env->NewStringUTF("HelloWorld来自jni的字符串");
  }

/*
 * Class:     com_example_mapplication_jniutil_NativeJNIMethod
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_mapplication_jniutil_NativeJNIMethod_add
  (JNIEnv *, jclass type, jint a, jint b){
    return a+b;
  }

四、调用native方法

在定义并实现好native方法后,下面的任务是编译成so库,然后就可以调用native方法了。

1、编译生成so库文件

    在第一部分中配置ndk标签,标签中指定了生成so库的名称以及支持的cpu型号。然后直接点击Build---->Rebuild Project即可生成对应的so文件libHelloJni.so(so库文件名称是lib加上你在ndk节点中定义的moduleName名称)。编译后so库文件路径如下,然后将armeabi-v7a和x86两个文件夹拷贝到libs文件夹中。

2、加载so库

    Android提供了4个实用的函数用来加载JNI库,分别是System.loadLibrary(libname),System.load(libFilePath),Runtime.getRuntime().loadLibrary(libname)和Runtime.getRuntime().load(libFilePath)。

    通过查看代码发现System.loadLibrary(libname)和System.load(libFilePath)最终调用的方法分别和Runtime.getRuntime().loadLibrary(libname),Runtime.getRuntime().load(libFilePath)调用的方法是一致的。所以这四种方法其实就是两种方式。

    虽然生成的so库文件名称是libHelloJni.so,当这个System.loadLibrary方法中写的库文件名称是你在ndk中moduleName 定义的名字"HelloJni"。

public class NativeJNIMethod {
    static {
        System.loadLibrary("HelloJni");
    }

    public static native String getNativieString();

    public static native int add(int a, int b);
}

3、以上工作完成后,就可以在java代码中调用native方法了

((TextView) findViewById(R.id.jni_tv)).setText(NativeJNIMethod.getNativieString());

findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
           int add = NativeJNIMethod.add(10, 15);
           ((TextView) findViewById(R.id.sum)).setText(Integer.toString(add));
      }
});


以上是实现简单JNI的操作步骤~,希望有所帮助。




猜你喜欢

转载自blog.csdn.net/white_wt/article/details/80534114
今日推荐