我有一个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()
。
我试着为您的用例放入部分代码。
-
在
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); }
-
在本机端,您保留对象的引用,并在适当的时间调用
//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); }