Search code examples
androidjava-native-interfacenative

Get Java VM pointer in global object constructor in Android native code before JNI_OnLoad


I have a global object in native code which need to call Java code in it's constructor. Normally to get JavaVM pointer, I get the in JNI_OnLoad and cache it.

But the global object constructor is get called before JNI_OnLoad. And since you cannot really call JNI_GetCreatedJavaVMs or JNI_CreateJavaVM from Android native code.

Does anyone know how to get a JavaVM pointer before JNI_OnLoad get called?

Your help is appreciated.


Solution

  • For the sake of clarity, let's assume that you have libziron.so that has a global object with constructor that needs JavaVM* vm.

    Build another library, lib1.so, which will have only

    JavaVM* g_vm;
    
    jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
    {
        g_vm = vm;
        return JNI_VERSION_1_4;
    }
    

    In Java, you load lib1.so and after that libziron.so. In libziron.so, you can now access extern g_vm. Note that while libziron.so depends on lib1.so, you must load them manually, in the right order.