- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个使用 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/
我有一个由我公司开发的私有(private)库。它允许我设置一个回调函数,这样长时间操作完成后,回调将在子线程中调用。 我应该在回调中操作JVM。这是我在回调函数中的主要代码: JNIEnv *pEn
我正在从 C 代码调用 Java 方法。每次调用时,我调用 AttachCurrentThread,调用后调用 DetachCurrentThread。 这工作正常,但问题是我看到由此引起的连续垃圾收
我很抱歉问了一个非常模糊的问题,但是,我有一个纯原生的 NDK 应用程序,它应该在沉浸模式(即全屏)下执行。 沉浸式模式 JNI fragment 在应用程序通过 APP_CMD_RESUME 恢复时
我一直在阅读有关 JNI 的内容,但似乎无法弄清楚如果线程启动 -> 调用 AttachCurrentThread() -> 进行一些 JNI 调用 -> 线程退出会发生什么。 理想情况下,我们应该在
我在使用 lib Vlc for android 的应用程序中收到此警告。 W/art: Native thread exiting without having called DetachCurre
我有一个使用 NDK 的 Android 应用程序 - 一个具有常规 UI 和 C++ 核心的常规 Android Java 应用程序。在核心中有些地方我需要调用 Java 方法,这意味着我需要该线程
我是一名优秀的程序员,十分优秀!