当前位置: 首页 > 知识库问答 >
问题:

通过JNI从其他线程调用已保存的Java对象

拓拔弘化
2023-03-14

我有一个通过JNI调用C++共享对象的Java对象。在C++中,我保存了对JNIEnv和JObject的引用。

JavaVM * jvm;
JNIEnv * myEnv;
jobject myobj;

JNIEXPORT void JNICALL Java_org_api_init
   (JNIEnv *env, jobject jObj) {
    myEnv = env;
    myobj = jObj;
}

我还有一个GLSurface呈现器,它最终在一个不同的线程glthread上调用上面提到的C++共享对象。然后,我试图使用我最初保存的jobject回调到我最初的Java对象,但我想,因为我在GLThread上,我得到了以下错误。

W/dalvikvm(16101): JNI WARNING: 0x41ded218 is not a valid JNI reference
I/dalvikvm(16101): "GLThread 981" prio=5 tid=15 RUNNABLE
I/dalvikvm(16101):   | group="main" sCount=0 dsCount=0 obj=0x41d6e220 self=0x5cb11078
I/dalvikvm(16101):   | sysTid=16133 nice=0 sched=0/0 cgrp=apps handle=1555429136
I/dalvikvm(16101):   | schedstat=( 0 0 0 ) utm=42 stm=32 core=1

回Java的代码:

void setData()
    {
        jvm->AttachCurrentThread(&myEnv, 0);

        jclass javaClass = myEnv->FindClass("com/myapp/myClass");
        if(javaClass == NULL){
            LOGD("ERROR - cant find class");
        }

        jmethodID method = myEnv->GetMethodID(javaClass, "updateDataModel", "()V");
        if(method == NULL){
            LOGD("ERROR - cant access method");
        }

        // this works, but its a new java object
        //jobject myobj2 = myEnv->NewObject(javaClass, method);

        //this is where the crash occurs
        myEnv->CallVoidMethod(myobj, method, NULL); 

}

如果我使用env->newobject创建了一个新的jObject,我可以成功地回调到Java,但它是一个新对象,我不想这样。我要回到我最初的Java目标。

在我回Java之前是不是要换个线程?如果是,我如何做?

共有1个答案

汲丰茂
2023-03-14

从不同的线程访问对象是很好的。问题是JNI调用将获取对象作为本地引用。如果希望在JNI调用之间保持对jobject的引用,则需要使其成为全局引用:

myobj = env->NewGlobalRef(jObj);

记住在使用完后释放它,否则垃圾收集器不会收集它,并且会导致内存泄漏:

myEnv->DeleteGlobalRef(myobj);

在这里阅读关于全局参考和本地参考。

 类似资料:
  • 总结:当从本机创建的线程上的本机代码调用Java时,我看到Java线程泄漏。 (2014年2月11日更新:我们向Oracle提出了支持请求。Oracle已在Java 7 Update 45上确认了这一点。它只影响64位Linux(可能还有Mac)平台:32位Linux不受影响)。 (2014年4月29日更新:Oracle对此问题进行了修复,并将在Java 7 Update 80中发布)。 我有一个

  • 问题内容: 如何通过 JNI 从Node.js调用Java ?有没有例子? 问题答案: 看起来很棘手。Node.JS在Google Chrome JavaScript引擎V8上运行。您将要做的是创建一个V8 C ++绑定(一个v8 c ++崩溃课程 显示了一个示例),该绑定启动JVM并执行所有JNI处理。 我认为让JavaServer和Node.js通过网络进行通信可能更好(有人写了一个使用Rab

  • 我有一个Android应用程序,需要使用库。我正在使用与它进行接口。该库使用一个结构(我们称之为)。使用一组初始参数,其中包括指向函数的指针,它使用这些函数从我的应用程序请求更多数据,并将这些数据合并到计算过程中。一旦它拥有了所需的一切,它就会通过回调函数返回一个结果,它还需要一个指针。我需要将所有的回调函数挂接到我的应用程序中,从用户那里获取更多的数据,然后将这些数据返回到中,最后通过最终的回调

  • 有没有哪位C专家曾经在C中实现过Epoll非阻塞选择器,我可以从Java调用它,这样我就不必使用Java的NIO Epoll实现了?

  • 因此,有人知道如何杀死一个线程,同时它调用任何JNI函数而不使用while循环。

  • 问题内容: 我正在编写一个简单的Web应用程序以调用存储过程并检索一些数据。它是一个非常简单的应用程序,可以与客户的数据库进行交互。我们传递员工ID和公司ID,存储过程将返回员工详细信息。 Web应用程序无法更新/删除数据,并且正在使用SQL Server。 我正在Jboss AS中部署Web应用程序。我应该使用JPA访问存储过程还是。在这种情况下使用JPA的任何优势。 调用该存储过程的sql语句