从JNI访问Java类对象方法



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

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

有可能做到吗?

这是我的活动:

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

最新更新