工程中需要以下文件:
CMakeList.txt 配置文件
jni_native_lib.cpp cpp文件
DynamicNative.java java中定义native方法文件
MainActivity.java 显示的activity
app/build.gradle
通过动态注册的方式进行函数的调用
CMakeList.txt
cmake_minimum_required(VERSION 3.10.2)
project("nativectest")
//cpp_source后面可以接一个文件或者多个文件
file(GLOB cpp_source jni_native_lib.cpp)
//通过cpp_source字段进行配置
add_library(jni_native_lib SHARED ${cpp_source})
find_library(log-lib log)
target_link_libraries(jni_native_lib ${log-lib})
jni_native_lib.cpp
#include <jni.h>
#include <string>
#include <Android/log.h>
#define LOG_TAG "System.out"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
//通过宏定义类路径及名称(注意是反斜杠)
#define JAVA_CLASS "com/org/nativectest/JNIClass"
//定义native中的方法,需要传入两个参数
jstring getMessage(JNIEnv *env, jobject jobj) {
return env->NewStringUTF("get message from cpp-lib jni");
};
static JNINativeMethod gMethod[] = {
//java中的方法名称,方法签名(需要查看方法签名规则),cpp中的对应的方法名称
{"getNativeString", "()Ljava/lang/String;", (void *) getMessage}
};
int registerNativeMethods(JNIEnv *env, const char *name, JNINativeMethod *methods, jint nMethods) {
jclass jcls;
jcls = env->FindClass(name);
if (jcls == nullptr) {
return JNI_FALSE;
}
//对java中的native方法进行注册
if (env->RegisterNatives(jcls, methods, nMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_FALSE;
}
//通过传入env,类名称,方法名数组,数组索引数
registerNativeMethods(env, JAVA_CLASS, gMethod, 1);
//通过头文件的引入实现日志输出的功能
LOGI(">>>>>>>>>>>>>>>>>>>");
return JNI_VERSION_1_6;
}
DynamicNative.java
package com.org.nativectest;
public class DynamicNativie {
static {
//下面导入的是CMakeList文件中target_link_libraries后面的lib名称
System.loadLibrary("jni_native_lib");
}
public native String getNativeString();
}
MainActivity.java
package com.org.nativectest;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DynamicNativie jniClass = new DynamicNativie();
TextView tv = findViewById(R.id.sample_text);
tv.setText(jniClass.getNativeString());
}
}
build.gradle
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}