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.
Pass the custom object during
onCreate
toJNI
//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); }
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); }