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).
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?
Note that according to the documentation APP_CMD_RESUME
executes from main thread.
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.
documentation, ANativeActivity::env is JNI context for the main thread of the app.
You should call DetachCurrentThread()
before terminating a native thread that you attached to JVM.
You should not call DetachCurrentThread)
on a thread born in Java, e.g. the UI thread.
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:
use
pthread_key_create
to define a destructor function that will be called before the thread exits, and callDetachCurrentThread
from there. (Use that key withpthread_setspecific
to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
See how WebRTC handles attach/detach in their git Web repo.