Home > database >  Access Java class object methos from JNI
Access Java class object methos from JNI

Time:04-09

I have an Android app in which I have implemented the connection with a WebSocket in the C code.

Now I would like to invoke a method of an object initialized in the Java class, via C code with JNI.

It's possible to do it?

This is my Activity:

public class MainActivity extends AppCompatActivity{

private MyCustomObject object; //This object is initialized in the life cycle of the activty

}

What I want to do is call object.myCustomMethod() from JNI.

CodePudding user response:

I tried to put the part of code for your use case.

  1. Pass the custom object during onCreate to JNI

     //MainActivity.java
     public class MainActivity extends AppCompatActivity {
    
        // Used to load the 'native-lib' library on application startup.
    
        static {
            System.loadLibrary("native-lib");
        }
    
        private MyCustomObject object;
    
        protected void onCreate(Bundle savedInstanceState) {
    
            object = new MyCustomObject();
    
            //object is passed tthrough JNI call
            intJNI(object);
        }
    
        public class MyCustomObject{
    
            public void myCustomMethod(){
    
            }
    
        }
    
    
        /**
         * A native method that is implemented by the 'native-lib' native library,
         * which is packaged with this application.
         */
        public native void intJNI(MyCustomObject obj);
    }
    
  2. At native side you keep the reference of the object and call it at appropriate time

    //JNI 
    static jobject globlaRefMyCustomObject;
    static JavaVM *jvm;
    
    extern  "C" JNIEXPORT void JNICALL
    Java_test_com_myapplication_MainActivity_intJNI(
            JNIEnv* env,
            jobject callingObject,
            jobject myCustomObject) {
    
            jint rs = env->GetJavaVM(&jvm);
            assert (rs == JNI_OK);
    
            //take the global reference of the object
            globlaRefMyCustomObject =     env->NewGlobalRef(myCustomObject);
    
    }
    
    //this is done in any background thread in JNI 
    void callJavaCallbackFucntion(){
    
         JNIEnv *env;
         jint rs = jvm->AttachCurrentThread(&env, NULL);
         assert (rs == JNI_OK);
    
        jclass MyCustomObjectClass = env->GetObjectClass(globlaRefMyCustomObject);
        jmethodID midMyCustomMethod = env->GetMethodID(MyCustomObjectClass, "myCustomMethod", "()V");
        env->CallVoidMethod(globlaRefMyCustomObject,midMyCustomMethod);
    
        /* end useful code */
        jvm->DetachCurrentThread();
    }
    
    
    //Release the Global refence at appropriate time
    void JNI_OnUnload(JavaVM *vm, void *reserved){
        JNIEnv* env;
        if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
            return JNI_ERR;
        }
        env->DeleteGlobalRef(globlaRefMyCustomObject);
    }
    
  • Related