使用流程
1、在java文件中创建本地方法
2、build项目后自动生成“.h”文件
3、创建.cpp文件,实现.h文件中的方法
4、配置Cmake文件,生成“.so”文件
笔者项目目录如下:
测试实例
public class MyJNI {
private static final String TAG=MyJNI.class.getName();
@Test
public void test(){
JNITest jniTest=new JNITest();
Log.d(TAG,jniTest.nativeCalculate(2)+"");
}
}
1、调用native方法nativeCalculate,传入参数2。
1、获取java对象number,初始值为0。
2、调用java方法javajavaCalculate,传入number值,获得返回值10。
3、将返回值加上参数2,返回,获得12。
最终效果如下:
创建本地方法
public class JNITest {
private int number = 0;
public int javaCalculate(int num){
number=num+10;
return number;
}
public native int nativeCalculate(int num);
static {
System.loadLibrary("jni_test");
}
}
自动生成“.h文件”
首先make Project,然后进入到app\build\intermediates\classes\debug目录下。
在终端输入命令javah com.example.xujiajia_sx.jnitest.JNITest(即带有native方法的类)
效果如下:
自动生成的“.h”文件如下,可以根据自己要求对其重命名或者增减内容。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_xujiajia_sx_jnitest_JNITest */
#ifndef _Included_com_example_xujiajia_sx_jnitest_JNITest
#define _Included_com_example_xujiajia_sx_jnitest_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_xujiajia_sx_jnitest_JNITest
* Method: nativeCalculate
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_example_xujiajia_1sx_jnitest_JNITest_nativeCalculate
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
创建cpp文件实现native方法
笔者cpp文件如下:
#include "jni_test.h"
JNIEXPORT jint JNICALL
Java_com_example_xujiajia_1sx_jnitest_JNITest_nativeCalculate(JNIEnv *env, jobject obj,jint num) {
//获取obj中对象的class对象
jclass clazz = env->GetObjectClass(obj);
//获取clazz中的number字段的id
jfieldID id_number = env->GetFieldID(clazz, "number", "I");
jmethodID id_java_calculate=env->GetMethodID(clazz, "javaCalculate", "(I)I");
//次获取java中number的值
jint number = env->GetIntField(obj, id_number);
jint result=env->CallIntMethod(obj,id_java_calculate,number);
env->SetIntField(obj,id_number,result+num);
//再次获取java中number的值并返回
return env->GetIntField(obj, id_number);
}
主要逻辑是获取到java中number的值,然后调用javaCalculate()方法,接着再加上这个native方法的参数num。
设置Cmake文件,生成".so"文件
首先,在build.gradle中添加Cmake配置:
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags ""
//生成多个版本的so文件
abiFilters 'armeabi','armeabi-v7a','x86'
}
}
}
buildTypes {
...
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
编写Cmake文件:
#CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
jni_test
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/jni/jni_test.cpp)
include_directories(src/main/jni/)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
# 制定目标库.
jni_test
# Links the target library to the log library
# included in the NDK.
${log-lib} )
配置完cmake,rebuild项目,即可以运行test。“.so”文件生成如下: