Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JNI参数是本地或全局引用_Java_Android_Android Ndk_Java Native Interface - Fatal编程技术网

Java JNI参数是本地或全局引用

Java JNI参数是本地或全局引用,java,android,android-ndk,java-native-interface,Java,Android,Android Ndk,Java Native Interface,我在JNI中阅读了几篇关于本地和全局引用的参考文献。但我找不到一个明确的答案,即作为参数传递给JNI函数的Java对象是本地引用还是全局引用。我认为它应该是全球性的,但有一个问题: 首先,我获取Java对象指针并保存它。然后本机回调函数调用该对象的方法。回调函数是从单独的线程调用的。该线程是使用AttachCurrentThread()创建的,因此JVM知道它。JNIEnv*变量也是有效的,并且该对象没有被垃圾调用,但是我得到警告,然后崩溃 JNI警告:0x4108edb8不是中的有效JNI引用

我在JNI中阅读了几篇关于本地和全局引用的参考文献。但我找不到一个明确的答案,即作为参数传递给JNI函数的Java对象是本地引用还是全局引用。我认为它应该是全球性的,但有一个问题:

首先,我获取Java对象指针并保存它。然后本机回调函数调用该对象的方法。回调函数是从单独的线程调用的。该线程是使用AttachCurrentThread()创建的,因此JVM知道它。JNIEnv*变量也是有效的,并且该对象没有被垃圾调用,但是我得到警告,然后崩溃

JNI警告:0x4108edb8不是中的有效JNI引用 Lcom/my/company/MyClass;。load:(Ljava/lang/String;)V(GetObjectClass)


从理论上讲,如果函数不是从Java代码调用的,那么您可以得到一个全局ref(我有时直接从其他JNI方法调用我的JNI方法,而不要求JVM这样做),但是您应该始终假设它们是本地的,并像这样对待它们。如果要存储它们以供以后使用,则应创建一个新的gobal引用。 事实上,即使你能得到一个全球参考,你应该如何对待他们也没有什么区别。在任何情况下,您都不必删除它们,即使您碰巧获得了一个全局引用(我认为上面描述的方法是唯一的方法),在不首先对其进行新引用的情况下存储它们也是错误的。如果给你的人删除了ref,它就会失效


编辑:以上是一个经过编辑的版本,我希望它能让@EJP更满意。同样的信息,只是更清晰。他确实有一点,对于几乎所有的情况,JNI规范都是最重要的,即使在这种情况下它没有什么区别:-)

理论上,如果函数不是从Java代码调用的,你可以得到一个全局引用(我有时直接从其他JNI方法调用我的JNI方法,而不要求JVM这样做)但你应该始终假设他们是本地人,并像那样对待他们。如果要存储它们以供以后使用,则应创建一个新的gobal引用。 事实上,即使你能得到一个全球参考,你应该如何对待他们也没有什么区别。在任何情况下,您都不必删除它们,即使您碰巧获得了一个全局引用(我认为上面描述的方法是唯一的方法),在不首先对其进行新引用的情况下存储它们也是错误的。如果给你的人删除了ref,它就会失效

编辑:以上是一个经过编辑的版本,我希望它能让@EJP更满意。同样的信息,只是更清晰。他确实有一点,对于几乎所有的情况,JNI规范是最重要的,即使它在这种情况下没有任何区别:-)

  • 这是当地的参考资料

  • JNIEnv*指针在JNI方法调用边界上无效,更不用说线程边界了

  • 在您的环境中,必须将本地引用转换为全局引用,以便回调方法使用

  • 这是当地的参考资料

  • JNIEnv*指针在JNI方法调用边界上无效,更不用说线程边界了

  • 在您的环境中,必须将本地引用转换为全局引用,以便回调方法使用


  • 我想你是对的,因为我刚试过新的GlobalRef,没有崩溃。谢谢完成后不要忘记调用DeleteGlobalRef(),否则将导致对象及其引用的所有内容的内存泄漏。Yep。我认为我最好使用NewWeakGlobalRef(),因为使用NewGlobalRef()这个对象根本不会被释放。请再问一个问题。finalize()Java方法是清理所有本机资源的有效场所吗?它们有不同的用途。。。如果执行NewGlobalRef(),则必须调用DeleteGlobalRef()(然后它将用于gc)。有了NewWeakGlobalRef,你的工作项目就有可能在你需要的时候消失。这是否正确取决于您的用例。记住在使用它之前检查它是否有效,或者无论你调用什么都可能崩溃,在最好的情况下有例外,在最坏的情况下很难。认为你是对的,因为我刚刚尝试了NewGlobalRef,没有崩溃。谢谢完成后不要忘记调用DeleteGlobalRef(),否则将导致对象及其引用的所有内容的内存泄漏。Yep。我认为我最好使用NewWeakGlobalRef(),因为使用NewGlobalRef()这个对象根本不会被释放。请再问一个问题。finalize()Java方法是清理所有本机资源的有效场所吗?它们有不同的用途。。。如果执行NewGlobalRef(),则必须调用DeleteGlobalRef()(然后它将用于gc)。有了NewWeakGlobalRef,你的工作项目就有可能在你需要的时候消失。这是否正确取决于您的用例。记住在你使用它之前要检查它是否有效,或者你所调用的任何东西都可能崩溃,最好的情况是例外,最坏的情况是硬的。