DetachCurrentThread 有时在 NDK 中崩溃 [英] DetachCurrentThread crashes sometimes in NDK

查看:42
本文介绍了DetachCurrentThread 有时在 NDK 中崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I excuse for asking a quite vague question, but, I have a pure native NDK application which is supposed to execute in Immersive Mode (i.e fullscreen).

沉浸式模式 JNI 片段在应用通过 APP_CMD_RESUME 恢复时执行.这在大多数情况下都有效,但是我的 SetImmersiveMode() 片段中的命令 activity->vm->DetachCurrentThread() 时不时会崩溃并导致致命例外:

The immersive mode JNI snippet is executed when the app is resumed via APP_CMD_RESUME. This works most of the time, but, every now and then the command activity->vm->DetachCurrentThread() in my SetImmersiveMode() snippet crashes with a fatal exception:

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)

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

This really boggles me, mainly because it happens every now and then, how can I detect if I'm executing from this original thread?

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

Note that according to the documentation APP_CMD_RESUME executes from main thread.

推荐答案

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

View.setSystemUiVisibility() should be called from the main thread only. Without seeing your code, it's hard to tell if DetachCurrentThread() plays any role in this.

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

documentation, ANativeActivity::env is JNI context for the main thread of the app.

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

You should call DetachCurrentThread() before terminating a native thread that you attached to JVM.

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

You should not call DetachCurrentThread) on a thread born in Java, e.g. the UI thread.

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

Note that you may call AttachCurrentThread() at any time and on any thread. It will be equivalent to NOP on a Java thread or on an attached thread.

这些附加/分离不像括号那样配对.任何数量的附加调用都可以通过单次分离来反转.推荐做法:

These attach/detach are not paired like parentheses. Any number of attach calls is reversed by single detach. The recommended practice:

使用pthread_key_create定义一个析构函数,在线程退出前调用,并从那里调用DetachCurrentThread.(使用该键和 pthread_setspecific 将 JNIEnv 存储在 thread-local-storage 中;这样它将作为参数传递到您的析构函数中.)

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.)

在他们的 git Web repo.

这篇关于DetachCurrentThread 有时在 NDK 中崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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