前言:
在Java中,如果想要调用底层.c或者c++,需要通过JNI是实现双端的互通,这篇就来说说在java中如何通过JNI来调用c++模块
一、配置build.gradle 中sdk 相关的设置
defaultConfig {
...
//这个是配置c++的版本
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
}
}
//配置设备CPU的类型, 一般只需要配置arm64-v8a跟armeabi-v7a这两个就可以了,
//这两个型号的机型占市面上的90%
ndk {
abiFilters "arm64-v8a", "armeabi-v7a", "x86","x86_64"
ldLibs "jnigraphics"
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
//配置.so 或者.a 文件存放位置
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
//CMake 位置及版本号
externalNativeBuild {
cmake {
path "src/main/jni/CMakeLists.txt"
version "3.10.2"
}
}
//NDK的版本
ndkVersion '23.1.7779620'
二、定义native方法
public class NDKTool {
public native String callNative(String string);
}
三、JNI中.h 预定义 c++方法
extern "C"
JNIEXPORT jstring JNICALL Java_com_example_testmyproject_NDKTool_callNative
(JNIEnv *, jobject, jstring);
四、编写.cpp文件
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_testmyproject_NDKTool_callNative(JNIEnv *env, jobject thiz, jstring string) {
// TODO: implement callNative()
//获取字符串指针,必须使用指针,不能使用char strContent[],因为GetStringUTFChars()返回值为const char *;
const char *strContent = env->GetStringUTFChars(string, JNI_FALSE);
char str[] = "欢迎你的到来!";
//字符串拼接,实现strContent+str1,因为strcat的第一个参数必须为非const类型(可变),所以不能直接使用strcat()
//创建一个新的字符串指针
char *strTemp = (char *) malloc(strlen(strContent) + strlen(str) + 1);
//拷贝常量到字符串指针
strcpy(strTemp,strContent);
//拼接str到strTemp
strcat(strTemp,str);
//返回一个utf的jstring
return env->NewStringUTF(strTemp);
}
五、创建CMakeLists.txt 并添加 .so动态库
cmake_minimum_required(VERSION 3.4.1)
add_library(
NDKTool
SHARED
# Provides a relative path to your source file(s).
${CMAKE_CURRENT_SOURCE_DIR}/NDKTool.cpp)
六、在java中加载动态库
public static void loadLibrary() throws RuntimeException {
try {
System.out.println("load start");
System.loadLibrary("NDKTool");
System.out.println("load ndkTool.so end");
} catch (UnsatisfiedLinkError e) {
System.out.println("load ndkTool.so error");
e.printStackTrace();
}
}
只需要用你的小手点个赞,就可以免费拿走源代码:
https://github.com/xzq199946/JNI_Test_Project.git