概述
JNI(JavaNative Interface)
是由Java语言提供的供Java和C/C++相互通信的机制,就是Java与C/C++的互调
NDK(Native Development Kit)
:本地开发工具集,用于快速开发C/C++的动态库.so文件,并和java一起打包到Apk.
使用NDK,主要基于以下原因:
1. 使用C/C++成熟的类库,而不需要重复造轮子
2. C/C++执行效率比java 高
实例
接下来我们主要通过Android Studio
来实现一个JNI
调用的HelloWorld
,
体验一下Studio
上JNI
的开发流程,场景就是Java调用C代码获取一段String 的返回值
一. 首先定义本地方法
public class NDKUtils {
static {
System.loadLibrary("jnitest");// moduleName,可以通过工程下的build.gradle来配置
}
public native String getStringFromJni();
}
这时候方法可能会报红,但是我们不需要管他,直接下一步即可
二. 编译
生成字节码文件是为了后面编译.so
库作准备的,生成class的过程,直接Build→Make Project
,这是就会在app/build/intermediates/classes/debug
生成相应的class文件
三. javah编译生成头文件
首先进入到build下的class目录中,执行如下命令
cd app/build/intermediates/classes/debug
javah -jni com.bobomee.android.androidndktest.NDKUtils
这时会在class文件所在目录生成相应的头文件
四. 实现头文件函数
上一步中生成的头文件是一个接口,如下所示
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_bobomee_android_androidndktest_NDKUtils */
#ifndef _Included_com_bobomee_android_androidndktest_NDKUtils
#define _Included_com_bobomee_android_androidndktest_NDKUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_bobomee_android_androidndktest_NDKUtils
* Method: getStringFromJni
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_bobomee_android_androidndktest_NDKUtils_getStringFromJni
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
从注释中,我们可以看到其方法的签名,返回值类型和class名称等,接下来就是实现了,首先将头文件拷贝到main目录中
,如main/jni
,并新建.c
文件.
//main/jni/NDKUtils.c
#include "com_bobomee_android_androidndktest_NDKUtils.h"
JNIEXPORT jstring JNICALL Java_com_bobomee_android_androidndktest_NDKUtils_getStringFromJni
(JNIEnv *env, jobject obj) {
return (*env)->NewStringUTF(env, "I`m form c,Hello world jni");
}
这里直接返回了一个String
五.配置编译环境
首先检查下local.properties
文件,看是否有NDK
环境,如下所示
其次,在gradle.properties
文件下添加NDK
支持,android.useDeprecatedNdk=true
编辑build.gradle,添加动态库配置,比如动态库Module名称ABI支持平台等
六. 调用
至此,JNI的HelloWorld
就算完成了,可以编写代码来测试一下了
NDKUtils ndkUtils = new NDKUtils();
TextView textView = (TextView) findViewById(R.id.text);
String text = ndkUtils.getStringFromJni();
textView.setText(text);//显示I`m form c,Hello world jni
最后生成的.so
动态库躲在路径为\build\intermediates\ndk\lib
,如果我们想把这个动态库给别人使用,只需要将其拷贝到jniLibs
下即可.