我最近开始使用我的Android JNI应用程序定位API级别14,并立即发现here所描述的问题。
未能通过显式管理本地引用来解决问题(在我的实验结束时获得了本地ref表溢出),我决定简单地切换到全局引用。现在我正在“尝试使用陈旧的全局引用”问题,该文章中没有描述。
这就是我要做的事情:有一个容器有jobject
s的单个对象。每当Java调用我的本机方法并传递我需要存储以供以后使用的引用时,我创建新的全局引用到jobject
,将全局引用添加到容器并存储其索引。每当我需要使用jobject
时,我都会通过索引获取它。这种方法有什么问题?
P上。 S.每当我调用JNI方法时,我使用正确的JNIEnv
作为调用线程。制作JNI调用的线程附加到JVM。
答案 0 :(得分:1)
未能通过显式管理本地引用来解决问题(在我的实验结束时获得了本地引用表溢出)
我在你的代码中发现了更深层次的问题。如果您知道正在创建的所有本地引用并且正确地手动删除它们,那么本地引用表溢出就不会发生,而不是从当前JNI调用返回。本地参考创建might be very subtle,不仅仅是FindClass
。
无论如何,如果你想让它与全局引用一起工作(这似乎是正确的事情,根据你描述的使用场景),我怀疑这个:你的“容器”需要那些存储的引用有时也被删除,不只是添加我猜。你确定要删除正确的那些,并在正确的那些上调用DeleteGlobalRef
,而不是留在容器中的其他人吗?换句话说,对于代码中的每个NewGlobalRef
,请确保您知道相关DeleteGlobalRef
的位置,并确信它何时以及为何被调用。
答案 1 :(得分:1)
让您的Java方法将对包含的jobject的引用传递给每个本机方法。这样它总是自动正确,根本不需要变成GlobalRef
,所以你不会得到局部变量表溢出,不得不担心DeleteGlobalRef()
等等。