当前位置: 首页 > news >正文

JNI回调用中不同线程的env无法找到正确的kotlin的class

不同线程都需要通过 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_cast<void**>(&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_cast<void**>(&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();
}
http://www.lryc.cn/news/405718.html

相关文章:

  • 免费HTML模板网站汇总
  • 大屏数据看板一般是用什么技术实现的?
  • 在 Kubernetes 中设置 Pod 优先级及其调度策略详解
  • Spring框架、02SpringAOP
  • 基于python的网络爬虫爬取天气数据及可视化分析
  • 【WPF开发】上位机开发-串口收发
  • ubuntu开启 远程登录 允许root远程登录
  • 《昇思25天学习打卡营第23天|RNN实现情感分类》
  • 机械设计基础B(学习笔记)
  • MybatisPlusException: Error: Method queryTotal execution error of sql 的报错解决
  • 人工智能领域的顶尖影响力人物(部分代表)
  • Python:jsonl文件转json文件,并做字段处理
  • 安全产品在防御勒索病毒中的作用
  • NVIDIA 完全过渡到开源 GPU 内核模块
  • learning-cxx 学习cpp 环境配置 + bug解决
  • PHP 多线程和异步编程的常见陷阱
  • STL 哈希 学习总结
  • vue3页面编写-导入导出excel、展开查询项等
  • Java学习 - Spring Boot整合 Thymeleaf 实例
  • ubuntu20.04安装终端终结者并设置为默认终端
  • 以Zookeeper为例 浅谈脑裂与奇数节点问题
  • 最新版kubeadm搭建k8s(已成功搭建)
  • C++学习笔记-友元函数的定义与使用
  • 熵、交叉熵、KL散度
  • THS配置keepalive(yjm)
  • 新加坡裸机云多IP服务器特性
  • 深入理解ADB:Android调试桥详解与使用指南
  • PACS-医学影像信息管理系统,全影像科室PACS源码,内置包括MPR、CMPR、VR等三维处理功能
  • 无人机搭载无人机反制设备可行性分析
  • MATLAB绘制方波、锯齿波、三角波、正弦波和余弦波、