成都市做网站的公司,做网站建设费用预算,在施工过程中某施工企业的安全,做网站要会哪些软件不同线程都需要通过 JavaVM 获取到的 JNIEnv 指针#xff0c; 如果有两个线程有两个 env。 其中一个是jni接口自己传过来的#xff0c;可以正常使用#xff0c;正常获取kotlin中的class。但是通过 JavaVM 新获取的env 无法找到kotlin的class
1. 确保线程已附加到 JVM
确保…不同线程都需要通过 JavaVM 获取到的 JNIEnv 指针 如果有两个线程有两个 env。 其中一个是jni接口自己传过来的可以正常使用正常获取kotlin中的class。但是通过 JavaVM 新获取的env 无法找到kotlin的class
1. 确保线程已附加到 JVM
确保每个线程在使用 JNIEnv 之前已附加到 JVM。可以在每个线程中调用 AttachCurrentThread
JavaVM* g_jvm nullptr;JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {g_jvm vm;return JNI_VERSION_1_6;
}void someJNIFunction() {JNIEnv* env;if (g_jvm-AttachCurrentThread(env, nullptr) ! JNI_OK) {// 处理错误return;}// 使用 env 进行 JNI 调用jclass cls env-FindClass(com/example/YourKotlinClass);if (cls nullptr) {// 处理类未找到的错误}// 线程使用完成后分离线程g_jvm-DetachCurrentThread();
}2. 确保正确缓存类引用关键类要转化成全局引用即可给不同env使用
确保类引用被正确缓存并且在不同的线程中可用。可以在 JNI_OnLoad 中缓存类引用
jclass g_yourKotlinClass; //这里是关键JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {g_jvm vm;JNIEnv* env;if (vm-GetEnv(reinterpret_castvoid**(env), JNI_VERSION_1_6) ! JNI_OK) {return JNI_ERR;}// 这部分代码也可以写在 someJNIFunction 内。 不一定要写在JNI_OnLoad内jclass localClass env-FindClass(com/example/YourKotlinClass);g_yourKotlinClass (jclass) env-NewGlobalRef(localClass);env-DeleteLocalRef(localClass);return JNI_VERSION_1_6;
}3. 例子完整示例代码
#include jni.h
#include android/log.h#define LOG_TAG JNI_OnLoad
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)JavaVM* g_jvm nullptr;
jclass g_yourKotlinClass nullptr;JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {g_jvm vm;JNIEnv* env;if (vm-GetEnv(reinterpret_castvoid**(env), JNI_VERSION_1_6) ! JNI_OK) {return JNI_ERR;}jclass localClass env-FindClass(com/example/YourKotlinClass);if (localClass nullptr) {return JNI_ERR; // 类加载失败}g_yourKotlinClass (jclass) env-NewGlobalRef(localClass);env-DeleteLocalRef(localClass);return JNI_VERSION_1_6;
}void someJNIFunction() {JNIEnv* env;if (g_jvm-AttachCurrentThread(env, nullptr) ! JNI_OK) {// 处理错误return;}if (g_yourKotlinClass nullptr) {LOGD(Kotlin class is null);return;}jmethodID methodID env-GetMethodID(g_yourKotlinClass, yourMethodName, ()V);if (methodID nullptr) {LOGD(Method ID not found);return;}jobject obj ... // 获取对象实例env-CallVoidMethod(obj, methodID);g_jvm-DetachCurrentThread();
}