从 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()
。
我试着把你的用例的部分代码。
在 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);
}
我有一个 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()
。
我试着把你的用例的部分代码。
在
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); }