从 JNI 访问 Java class 对象方法

Access Java class object methos from JNI

我有一个 Android 应用程序,我在其中使用 C++ 代码实现了与 WebSocket 的连接。

现在我想通过 C++ 代码和 JNI 调用在 Java class 中初始化的对象的方法。

可以吗?

这是我的 Activity:

public class MainActivity extends AppCompatActivity{

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

}

我想做的是从 JNI 调用 object.myCustomMethod()

我试着把你的用例的部分代码。

  1. onCreate 期间将自定义对象传递给 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. 在本机端,您保留对象的引用并在适当的时候调用它

    //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);
    }