移动到Android L版本后,AttachCurrentThread在多线程JNI中崩溃

时间:2015-02-20 01:50:54

标签: android multithreading service android-ndk java-native-interface

我已经实现了一个在启动过程中由系统服务器调用的服务。

我的服务有JNI实现,它创建了另一个线程。 拥有另一个线程的原因是具有在监视回调时取消操作的能力。

此机制在Android Kitkat版本中运行良好,但在Android L中崩溃。

在两个线程之间,我将从GetJavaVM(env)获取的JavaVM *存储到静态全局变量中。当然,这个共享数据受pthread互斥锁保护。

到目前为止,我已经尝试了以下内容,但下面的所有内容仍然崩溃了:

1)使用JavaVM *我通过将它存储到全局

从JNI onLoad()函数获得

2)在新线程中,因为在Android上只运行一个JavaVM,所以从调用android :: AndroidRuntime :: getJavaVM()获取vm;

3)调用NewGlobalRef()后,在主线程中存储vm信息。并保存了对共享数据的引用。新线程使用了NewGlobalRef()的引用。

有没有人知道Android L版本在JNI环境中发生了哪些重大变化?

更新:

进一步调试,我提到的解决方案1)或2)应该有效。 实际问题是由于垃圾收集运行更频繁。所以我保留的HAL指针不再有效......

这些链接很有用!!!

https://developer.android.com/guide/practices/verifying-apps-art.html

http://developer.android.com/training/articles/perf-jni.html

感谢所有评论!

1 个答案:

答案 0 :(得分:0)

L版本发生的变化是移植到ART,其失误比Dalvik灵活性低。

在线程之间共享JavaVM *是完全没问题的,你应该保持这种方式。

但是,稍后您使用此JavaVM *做什么?

JNIEnv *必须从同一个线程中检索和使用,不得跨线程使用。要使用JNIEnv *,必须已将一个线程附加到VM(使用AttachCurrentThread)。 在退出之前,还必须使用DetachCurrentThread分离线程。