Our problem in a nutshell is this: when we call our native code from Java, we don't execute the normal 'android_main', which normally receives app state. We can manually instantiate our methods, as shown in the code attached, but in that case app state is a null pointer since apparently we're missing something about polling the 'MagicLeapNativeAppGlue' to use the app state. We're trying to get the native app state for a global instance via the following. This compiles and links but triggers an exception when run on ML2:
extern "C" JNIEXPORT void JNICALL
Java_org_pytorch_demo_revok_MainActivity_00024pollRGBCamera_initializeCamera(JNIEnv *env, jobject /* this */, jlong nativeAppState) {
// Initialization code here
ALOGI("Initializing gCameraPhotoApp");
gCameraPhotoApp = CameraPhotoApp::getInstance(reinterpret_cast<android_app *>(nativeAppState));
if (gCameraPhotoApp != nullptr) {
gCameraPhotoApp->InitializeCamera();
} else {
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
}
}
Any advice on how to get app state via 'MagicLeapNativeAppGlue' or another method?
I take it Magic Leap provides 'MagicLeapNativeAppGlue' as its own mechanism for launching native code from a Java activity. If that's the case, it would be great to confirm that. We would need to follow the Magic Leap-specific guidelines for initializing native code from Java, so any reference would be very helpful.
In the ML world, I believe Android activity life cycle is controlled in Java and that android_main is called by AppGlue, not called by the OS. I believe ML AppGlue pairs android.app.NativeActivity in Java with android_native_app_glue.c in the main library which launches proxy events to a separate thread(s) in our native .so libraries.
to illustrate, here are snippets of our code to call initialization for the ML2 RGB camera using JNI:
extern "C" JNIEXPORT void JNICALL
Java_org_pytorch_demo_revok_MainActivity_00024pollRGBCamera_initializeCamera(JNIEnv *env, jobject /* this */, jlong nativeAppState) {
if (gCameraPhotoApp != nullptr) {
gCameraPhotoApp->InitializeCamera();
} else {
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
}
}
In C++ we compile to libraries which we load in Java and access through the entry points illustrated above:
// Declare native methods
public native void initializeNative(long nativeAppState);
public class pollRGBCamera {
public pollRGBCamera() {
System.loadLibrary("camera_photo");
}
// Declare native method
public native void initializeCamera();
public native void captureImage();