假设Java回调接口如下,JNI如何回调这么接口呢?
public interface Listener {
void onChanged(int state);
}
首先获取虚拟机指针,JNI_OnLoad系统自动调用。
JavaVM* javaVM = nullptr;
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK)
{
return -1;
}
javaVM = vm;
return JNI_VERSION_1_6;
}
注册回调接口
struct CallBack
{
jobject callbackObj;
jmethodID onChangedMD;
};
CallBack callBack;
int RegisterCallBack(JNIEnv *env, jobject obj, jobject Listener)
{
if (Listener== nullptr)
{
return -2;
}
jclass objClass = env->GetObjectClass(Listener);
callBack.callbackObj = env->NewGlobalRef(Listener);//创建对象的本地变量
//获取方法ID
callBack.onChangedMD = env->GetMethodID(objClass, "onChanged", "(I)V");
return 0;
}
获取JNIEnv指针,再通过JNIEnv指针调用该函数。
JNIEnv* AttachJava()
{
JNIEnv *java = nullptr;
if (javaVM)
{
int getEnvStat = javaVM->GetEnv((void **)&java, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED)
{
JavaVMAttachArgs args = { JNI_VERSION_1_6, 0, 0 };
javaVM->AttachCurrentThread(&java, &args);
}
else if (getEnvStat == JNI_EVERSION)
{
}
}
return java;
}
void OnChangedCallBack(int state)
{
//获取JNIEnv指针
JNIEnv* env = AttachJava();
//调用该函数
env->CallVoidMethod(callBack.callbackObj, callBack.onChangedMD, state);
}