android - DetachCurrentThread 有时会在 NDK 中崩溃

标签 android android-ndk java-native-interface android-fullscreen

我很抱歉问了一个非常模糊的问题,但是,我有一个纯原生的 NDK 应用程序,它应该在沉浸模式(即全屏)下执行。

沉浸式模式 JNI fragment 在应用程序通过 APP_CMD_RESUME 恢复时执行。这在大多数情况下都有效,但是,我的 SetImmersiveMode() fragment 中的命令 activity->vm->DetachCurrentThread() 时不时会崩溃并出现致命异常:

FATAL EXCEPTION: Thread-10
Process: com.toppluva.portis.LocalDebug, PID: 5474
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7380)
at android.view.ViewRootImpl.recomputeViewAttributes(ViewRootImpl.java:3478)
at android.view.View.setSystemUiVisibility(View.java:22587)

这真的让我感到困惑,主要是因为它时不时地发生,我如何检测我是否从这个原始线程执行?

请注意,根据文档,APP_CMD_RESUME 从主线程执行。

最佳答案

View.setSystemUiVisibility() 只能从主线程调用。 在没有看到您的代码的情况下,很难判断 DetachCurrentThread() 是否在其中发挥了任何作用。

文档,ANativeActivity::env 是应用程序主线程的 JNI 上下文。

在终止附加到 JVM 的 native 线程之前,您应该调用 DetachCurrentThread()

您不应该在 Java 中生成的线程上调用 DetachCurrentThread),例如用户界面线程。

请注意,您可以随时在任何线程上调用 AttachCurrentThread()。它将等同于 Java 线程或附加线程上的 NOP。

这些附加/分离不像括号那样配对。任何数量的附加调用都会被单个分离逆转。 recommended练习:

use pthread_key_create to define a destructor function that will be called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)

查看 WebRTC 如何在其 git Web repo 中处理附加/分离.

关于android - DetachCurrentThread 有时会在 NDK 中崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52339597/

相关文章:

android - 检索JSON中的特定字段

android - 了解 android 内部结构(深入系统)

java - 使用 JNI : are we releasing objects property? 内存泄漏

android - 选择项目后永久 NavigationView 失去焦点

Android:链接到预建的静态库

android - 在 Android NDK 中包含 GLES31

Android:制作原生视频播放器时应该使用什么?

如果没有 project.properties 文件,Android JNI 将无法编译

java - java.awt.Robot 的 native 源代码

java - 理解Java中的一个概念