无法在 JNI 中更新作业
Posted
技术标签:
【中文标题】无法在 JNI 中更新作业【英文标题】:Cannot renew jobject in JNI 【发布时间】:2012-08-28 19:54:31 【问题描述】:我的应用程序是一个带有一些本机代码的 android 应用程序。
Java 代码通过 new Thread(new Runnable) 启动一个线程,在本机代码中,我通过 AttachCurrentThread 将该线程附加到 JVM。
在该线程中调用的本机函数是一个无限循环,它将侦听简单事件(布尔变量)并调用另一个本机函数,该函数通过使用正确的 JNIEnv 指针和 jobject 将填充 Java 端的 2 个 java 变量,并且调用 void 方法来显示数据。该循环的原因是正常调用函数的开销(有很多分配和销毁要做)很可能是巨大的。
唯一的问题是,虽然我可以更新 JNIEnv 指针,但我不知道如何为作业对象执行此操作。
我所说的jobject是指通过这样的函数调用传递给本机代码的jobject
jint Java_com_example_example_MainActivity_NativeFunc( JNIEnv* env,
jobject obj)
return;
【问题讨论】:
如果您打算在本机代码中保留对对象的引用,则需要通过创建新的全局引用或新的弱全局引用来显式保留引用(并且可能稍后释放它)。在后一种情况下,您还需要在使用前检查是否与 null 等价。 如果您所说的“更新”是指别的意思,请解释一下,因为 AFAIK 的“更新”在 Java 中不是标准用语。 【参考方案1】:Java 代码通过 new Thread(new Runnable) 启动一个线程,在本机代码中,我通过 AttachCurrentThread 将该线程附加到 JVM。
您不必将 JVM 附加到使用 Java 代码创建的线程,它已经附加了。
如果我正确理解了您的问题,您会得到一次jobject
,并希望稍后在其他本机方法中访问该对象。为此,您可以使用NewGlobalRef:
jobject myGlobalReference = env->NewGlobalRef(obj);
您可以将 jobject
存储在一个全局 C/C++ 变量中,然后再使用它。它将一直有效,直到 JVM 死亡或您使用 DeleteGlobalRef 删除引用。请记住,只要您不删除全局引用,如果所有对它的 Java 引用都消失了,垃圾回收不会收集引用的对象!
【讨论】:
以上是关于无法在 JNI 中更新作业的主要内容,如果未能解决你的问题,请参考以下文章
Python Cloud Dataflow 中无法更新工作状态异常
从文件中动态更新 Qdialog 中的 QTextBrowser(由另一个作业更新)