gpt4 book ai didi

android - 无法执行 JavaVM->DetachCurrentThread() : "attempting to detach while still running code"

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:05:30 25 4
gpt4 key购买 nike

我有一个使用 NDK 的 Android 应用程序 - 一个具有常规 UI 和 C++ 核心的常规 Android Java 应用程序。在核心中有些地方我需要调用 Java 方法,这意味着我需要该线程的 JNIEnv*,这反过来意味着我需要调用 JavaVM->AttachCurrentThread() 获取有效的 env

以前,只是执行 AttachCurrentThread 并且根本没有费心去分离。它在 Dalvik 中运行良好,但一旦调用了 AttachCurrentThread 的线程在未调用 DetachCurrentThread 的情况下退出,ART 就会中止应用程序。所以我阅读了 JNI 引用资料,确实它说我必须调用 DetachCurrentThread。但是当我这样做时,ART 会中止该应用程序并显示以下消息:

attempting to detach while still running code

这里有什么问题,如何正确调用DetachCurrentThread

最佳答案

如果线程在没有分离的情况下退出,Dalvik 也会中止。这是通过 pthread 键实现的——参见 Thread.cpp 中的 threadExitCheck() .

线程可能不会分离,除非它的调用栈是空的。这背后的原因是为了确保在堆栈展开时正确释放任何资源,如监视器锁(即 synchronized 语句)。

按照规范的定义,第二次和后续的附加调用是低成本的空操作。没有引用计数,所以分离总是分离,不管发生了多少次附加。一种解决方案是添加您自己的引用计数包装器。

另一种方法是每次附加和分离。这由应用程序框架在某些回调中使用。这与其说是一个有意的选择,不如说是将 Java 源代码包装在主要用 C++ 开发的代码周围并试图硬塞功能的副作用。如果您查看 SurfaceTexture.cpp ,特别是JNISurfaceTextureContext::onFrameAvailable(),可以看到当SurfaceTexture需要调用Java语言的回调函数时,它会附加线程,调用回调,然后如果线程刚刚被附加它会立即将其分离。 “needsDetach”标志通过调用 GetEnv 来设置,以查看该线程之前是否已附加。

这在性能方面并不是一件好事,因为每个附加都需要分配一个 Thread 对象并执行一些内部 VM 内务处理,但它确实会产生正确的行为。

关于android - 无法执行 JavaVM->DetachCurrentThread() : "attempting to detach while still running code",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27923917/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com