【问题标题】:JNI cleanup and daemon threads in Android NDKAndroid NDK 中的 JNI 清理和守护线程
【发布时间】:2012-03-10 06:32:40
【问题描述】:

这就是JNI的流程

JNI_onLoad - 获取 JavaVM(获取用于调用静态方法的 jclass)

然后需要从Java调用一些东西到C:

GetEnv() 获取 JNIEnvAttachCurrentThread() 以使用它。
调用java方法
处理 java 方法返回值。
DetachCurrentThread() - 空闲线程
到了最后
DestroyJavaVM()

问题是:

  1. 那里调用 DestroyJavaVM(),如果我需要这样做?在我的主 Activity 的 onDestroy() 中?
  2. JNI_onUnload 是否曾经调用过,我必须在那里清理什么?
  3. 我是否需要存储在静态全局变量中的免费 jclass
  4. JNI 是否释放本地超出范围的 jarrays/jarrays 元素、字符串和字符串字符、函数返回后的作业对象,或者我必须始终注意这一点(调用 env->Release(something))
  5. AttachCurrentThreadAsDaemon()有什么好处和用途?

【问题讨论】:

    标签: java android c android-ndk java-native-interface


    【解决方案1】:
    1. 当您不再使用 JVM(可能在程序结束时)时,必须调用 DestroyJavaVM()。

    2. JNI_onUnload 在类被卸载时被调用(例如因为它的类加载器被删除了)。

    3. 释放一个 Class null 它的引用并删除它的类加载器。

    4. JNI jarrays/jarrays 元素、字符串和作业要么由 JVM 分配,要么使用 C 缓冲区(由您管理);前一种情况见#3。

    5. AttachCurrentThreadAsDaemon() 告诉 JVM 它不应该等待线程在关闭时退出(对守护进程很有帮助)。

    祝你好运!

    【讨论】:

    • 对于 3 年前的问题并“接受”为作者的相关答案的问题,-1 背后的逻辑是什么?
    • 我没有否决您的答案,但我明白为什么有些人可能会对此提出质疑。问题是 Android 特有的,但 Android 历来不支持类卸载,销毁 VM 没有多大价值。释放 jclass 引用与释放类不同,例如如果您在循环中执行此操作,则需要释放本地参考。一些原生数组必须被显式释放,例如在Get*ArrayElements 之后,但#4 并没有真正回答这个问题。
    • 没有人回答过这个问题,因此在 3 年后惩罚唯一(并被接受!)的答案是一个很好的激励措施,可以阻止人们用他们的“最佳知识”做出贡献。发人深省?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多