无法执行JavaVM-> DetachCurrentThread():QUOT;试图分离,同时仍在运行code" [英] Can't execute JavaVM->DetachCurrentThread(): "attempting to detach while still running code"

查看:3657
本文介绍了无法执行JavaVM-> DetachCurrentThread():QUOT;试图分离,同时仍在运行code"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用NDK Android应用 - 一个普通的Andr​​oid的Java应用程序与普通的用户界面和C ++核心。有在核心的地方,我需要调用Java方法,这意味着我需要一个的JNIEnv * 该线程,这反过来又意味着,我需要调用 JavaVM-> AttachCurrentThread()来得到有效的 ENV

I have an Android app that uses NDK - a regular Android Java app with regular UI and C++ core. There are places in the core where I need to call Java methods, which means I need a JNIEnv* for that thread, which in turn means that I need to call JavaVM->AttachCurrentThread() to get the valid env.

previously,只是在做 AttachCurrentThread 并没有刻意在所有分离。它在Dalvik的工作得很好,但ART尽快中止应用程序作为已调用 AttachCurrentThread 线程退出,而无需调用 DetachCurrentThread 。所以,我读过了JNI引用,实际上它说我必须调用 DetachCurrentThread 。但是,当我做到这一点,ART中止以下消息应用程序:

Previously, was just doing AttachCurrentThread and didn't bother to detach at all. It worked fine in Dalvik, but ART aborts the application as soon as a thread that has called AttachCurrentThread exits without calling DetachCurrentThread. So I've read the JNI reference, and indeed it says that I must call DetachCurrentThread. But when I do that, ART aborts the app with the following message:

试图分离,同时仍在运行code

attempting to detach while still running code

这里有什么问题,以及如何调用 DetachCurrentThread 是否正确?

What's the problem here, and how to call DetachCurrentThread properly?

推荐答案

Dalvik的也将中止,如果线程退出不拆。这是通过pthread的键来实现 - 见 threadExitCheck()中的 Thread.cpp

Dalvik will also abort if the thread exits without detaching. This is implemented through a pthread key -- see threadExitCheck() in Thread.cpp.

一个线程可以不分离,除非它的调用堆栈是空的。这样做的原因是为了确保像显示器锁定任何资源(即同步语句)都被正确释放为堆栈开卷。

A thread may not detach unless its call stack is empty. The reasoning behind this is to ensure that any resources like monitor locks (i.e. synchronized statements) are properly released as the stack unwinds.

的第二个和后续连接呼叫,如由规范,低成本空操作定义。有没有引用计数,所以总是分离分离,无论多少都华武官如何发生的。一种解决方案是增加自己的引用计数包装。

The second and subsequent attach calls are, as defined by the spec, low-cost no-ops. There's no reference counting, so detach always detaches, no matter how many attaches have happened. One solution is to add your own reference-counted wrapper.

另一种方法是附加和分离每一次。这是通过对某些回调该应用框架使用。这与其说是一个深思熟虑的选择,主要是在C ++开发的缠绕code Java源代码的副作用,并试图鞋拔的功能。如果你看<一个href=\"https://android.googlesource.com/platform/frameworks/base/+/lollipop-release/core/jni/android/graphics/SurfaceTexture.cpp\"相对=nofollow> SurfaceTexture.cpp ,特别是 JNISurfaceTextureContext :: onFrameAvailable(),你可以看到,当需要表面纹理调用Java语言的回调函数,它将附加线程,调用回调函数,然后如果线程只是附会立即分离。在needsDetach标志是通过调用设置 GETENV ,看是否线程pviously连接$ P $。

Another approach is to attach and detach every time. This is used by the app framework on certain callbacks. This wasn't so much a deliberate choice as a side-effect of wrapping Java sources around code developed primarily in C++, and trying to shoe-horn the functionality in. If you look at SurfaceTexture.cpp, particularly JNISurfaceTextureContext::onFrameAvailable(), you can see that when SurfaceTexture needs to invoke a Java-language callback function, it will attach the thread, invoke the callback, and then if the thread was just attached it will immediately detach it. The "needsDetach" flag is set by calling GetEnv to see if the thread was previously attached.

这是不是一个伟大的事情的性能,明智的,因为每个连接需要分配一个线程对象,并做一些内部VM看家,但它确实产生正确的行为。

This isn't a great thing performance-wise, as each attach needs to allocate a Thread object and do some internal VM housekeeping, but it does yield the correct behavior.

这篇关于无法执行JavaVM-&GT; DetachCurrentThread():QUOT;试图分离,同时仍在运行code&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆