什么"陈旧的全球参考"意味着如何存储jobject并在线程之间传递它们?

时间:2013-01-31 14:17:40

标签: android java-native-interface

我最近开始使用我的Android JNI应用程序定位API级别14,并立即发现here所描述的问题。

未能通过显式管理本地引用来解决问题(在我的实验结束时获得了本地ref表溢出),我决定简单地切换到全局引用。现在我正在“尝试使用陈旧的全局引用”问题,该文章中没有描述。

这就是我要做的事情:有一个容器有jobject s的单个对象。每当Java调用我的本机方法并传递我需要存储以供以后使用的引用时,我创建新的全局引用到jobject,将全局引用添加到容器并存储其索引。每当我需要使用jobject时,我都会通过索引获取它。这种方法有什么问题?

P上。 S.每当我调用JNI方法时,我使用正确的JNIEnv作为调用线程。制作JNI调用的线程附加到JVM。

2 个答案:

答案 0 :(得分:1)

  

未能通过显式管理本地引用来解决问题(在我的实验结束时获得了本地引用表溢出)

我在你的代码中发现了更深层次的问题。如果您知道正在创建的所有本地引用并且正确地手动删除它们,那么本地引用表溢出就不会发生,而不是从当前JNI调用返回。本地参考创建might be very subtle,不仅仅是FindClass

无论如何,如果你想让它与全局引用一起工作(这似乎是正确的事情,根据你描述的使用场景),我怀疑这个:你的“容器”需要那些存储的引用有时也被删除,不只是添加我猜。你确定要删除正确的那些,并在正确的那些上调用DeleteGlobalRef,而不是留在容器中的其他人吗?换句话说,对于代码中的每个NewGlobalRef,请确保您知道相关DeleteGlobalRef的位置,并确信它何时以及为何被调用。

答案 1 :(得分:1)

让您的Java方法将对包含的jobject的引用传递给每个本机方法。这样它总是自动正确,根本不需要变成GlobalRef,所以你不会得到局部变量表溢出,不得不担心DeleteGlobalRef()等等。