在Androidstudio 中 通过jni java 和c++相互调用实现方法

发布时间 2023-06-27 14:09:36作者: adam.li

在Androidstudio 中 通过jni java 和c++相互调用实现方法
1.创建 java native方法类
public class NativeAPI {
private static final String TAG = APP_TAG + "TestJni ";
static {
System.loadLibrary("testnative");
}

//从c++ so 中获取字符串
public native String stringFromJNI();
//c++ so 中回调的java方法
public void callBackFromNative(String strFromNative) {
Log.i(TAG, "callBackFromNative() strFromNative:" + strFromNative);
}
}
2.生成c++头文件
2.1.进入java NativeAPI.java所在目录,执行命令,会生成.NativeAPI.class 到 classfile目录下面
javac -d ./classfile/ NativeAPI.java
2.2.进入classfile目录,执行命令,会在classfile目录 生成jni目录,并生成NativeAPI.java的头文件
javah -d jni -jni com.android.demo.testnative.NativeAPI
3.编译so文件
进入module的src/main/目录,创建cpp目录,进入到cpp目录
3.1 拷贝com_android_demo_testnative_NativeAPI.h 到当前目录下面的public目录
3.2.拷贝生成的com_android_demo_testnative_NativeAPI.h 并修改文件名为com_android_demo_testnative_NativeAPI.cpp ,实现相关方法
JNIEXPORT jstring JNICALL Java_com_android_demo_testnative_NativeAPI_stringFromJNI
(JNIEnv * env, jclass obj) {

LOGI("NativeAPI_stringFromJNI 11");
//在c代码里面调用java代码里面的方法
// java 反射
//1 . 找到java代码的 class文件
// jclass (*FindClass)(JNIEnv*, const char*);
jclass javaclass = env->FindClass("com/android/demo/testnative/NativeAPI");
LOGI("NativeAPI_stringFromJNI 22");
if(javaclass==0){
//LOGI("find class error");
return env->NewStringUTF( "javaclass js null" );
}
LOGI("NativeAPI_stringFromJNI 33");
//LOGI("find class ");
//2 寻找class里面的方法
// jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID method1 = env->GetMethodID(javaclass,"callBackFromNative","(Ljava/lang/String;)V");
LOGI("NativeAPI_stringFromJNI 44");
if(method1==0){
//LOGI("find method1 error");
return env->NewStringUTF( "method1 js null" );
}
LOGI("NativeAPI_stringFromJNI 55");
//LOGI("find method1 ");
//3 .调用这个方法
// void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
jstring parm1 = env->NewStringUTF( "参数1");
env->CallVoidMethod(obj,method1,parm1);
LOGI("NativeAPI_stringFromJNI 66");

return env->NewStringUTF( "test on tringFromJNI" );
}
3.3 创建CMakeLists.txt 文件中配置 需要引用的 头文件和c++ 文件等信息,需要生成的so库 名称等
3.4 进入module的build.gradle中 配置externalNativeBuild 引用CMakeLists.txt,
android {
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
}
3.5 然后assemble 编译 ,可以在 src/main/ 目录下生成jniLibs 目录,目录内包含生成的so文件,
PS:虽然可以生成so,但是有其他报错,生成完 so后,需要将externalNativeBuild 配置注释掉,然后再编译 module 引用对应的so