【问题标题】:Cannot renew jobject in JNI无法在 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 中不是标准用语。

标签: android c java-native-interface


【解决方案1】:

Java 代码通过 new Thread(new Runnable) 启动一个线程,在本机代码中,我通过 AttachCurrentThread 将该线程附加到 JVM。

您不必将 JVM 附加到使用 Java 代码创建的线程,它已经附加了。

如果我正确理解了您的问题,您会得到一次jobject,并希望稍后在其他本机方法中访问该对象。为此,您可以使用NewGlobalRef:

jobject myGlobalReference = env->NewGlobalRef(obj);

您可以将 jobject 存储在一个全局 C/C++ 变量中,然后再使用它。它将一直有效,直到 JVM 死亡或您使用 DeleteGlobalRef 删除引用。请记住,只要您不删除全局引用,如果所有对它的 Java 引用都消失了,垃圾回收不会收集引用的对象!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    相关资源
    最近更新 更多