java findclass,JNI多线程中findclass找不到自定义类

问题:

我要用ndk编译c++的代码,其中包含了多线程,主线程和回调线程。

在主线程中使用env->GetJavaVM(&g_jvm);得到了全局的vm,

在回调线程中我首先得到了env:

JNIEnv* env = NULL;

g_jvm->AttachCurrentThread(&env, NULL);

然后利用

jclass cls = env->FindClass("vc/db/DataSearchService");

(其中vc/db是包名,DataSearchService是自定义的类名)

在主线程中调用 env->FindClass("vc/db/DataSearchService");是没有问题的

解决方案:

1.在主线程调用 jclass cls = env->FindClass("vc/db/DataSearchService"); 然后用NewGlobalRef为这个cls申请全局引用,否则这只是个局部引用,跨线程仍然挂。

typedef struct java_callback {

int code;

jobject obj;

jobject cls;//回调需要的java bean

void *response;

} java_callback;

java_callback javaCallback;

JNIEXPORT void JNICALL

Java_com_xxx_xxx_testCallback(JNIEnv *env, jobject thiz, jobject query_order_listener) {

javaCallback.obj = (env)->NewGlobalRef(query_order_listener);

jclass cls= env->FindClass("com/xxx/xxx/QueryOrderBean");

javaCallback.cls = env->NewGlobalRef(cls);

}

/**

* 在此处跑在子线程中,并回调到java层

*/

void *callbackThreadHandler(void *p) {

if (p == NULL) {

logE("callbackThreadHandler>>>p is NULL");

pthread_exit(&callbackThread);

}

JNIEnv *env;

//获取当前native线程是否有没有被附加到jvm环境中

int getEnvStat = g_VM->GetEnv((void **) &env, JNI_VERSION_1_6);

if (getEnvStat == JNI_EDETACHED) {

//如果没有,主动附加到jvm环境中,获取到env

if (g_VM->AttachCurrentThread(&env, NULL) != 0) {

pthread_exit(&callbackThread);

}

}

//强转回来

auto jcallback = (java_callback *) p;

//通过强转后的jcallback 获取到要回调的类

jclass javaClass = env->GetObjectClass(jcallback->obj);

if (javaClass == 0) {

logE("Unable to find class");

g_VM->DetachCurrentThread();

pthread_exit(&callbackThread);

}

//获取要回调的方法ID 参数1:类名, 参数2:方法名, 参数3:方法名的签名

jmethodID javaCallbackId = env->GetMethodID(javaClass, "onQueryOrder",

"(Lcom/xxx/xxx/QueryOrderBean;)V");

if (javaCallbackId == NULL) {

logE("Unable to find method: onFaceDetect");

pthread_exit(&callbackThread);

}

//找到对象的Java类

auto queryOrderClass = (jclass) jcallback->cls;

// 获取类的构造函数,记住这里是调用无参的构造函数

jmethodID id = env->GetMethodID(queryOrderClass, "", "()V");

// 创建一个新的对象

jobject queryOrderBean = env->NewObject(queryOrderClass, id);

//对应的java属性

jfieldID time = env->GetFieldID(queryOrderClass, "time", "Ljava/lang/String;");

//属性赋值,queryOrderBean

env->SetObjectField(queryOrderBean, time, env->NewStringUTF(response2021->time));

//执行回调

env->CallVoidMethod(jcallback->obj, javaCallbackId, queryOrderBean);

env->DeleteLocalRef(queryOrderBean);

}

class QueryOrderBean {

val time: String = ""

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值