版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/atian123kiss/article/details/80622197
/**
* Global Reference of java method
* 回调函数object引用
*/
static jobject jSourceCallback;
/**
* the references of JVM
*/
static JavaVM *gJavaVM;
JNIEXPORT jint JNICALL Java_com_nativeSetCallBack
(JNIEnv *env, jobject obj, jobject callback) {
(*env)->GetJavaVM(env, &gJavaVM);
jSourceCallback = (*env)->NewGlobalRef(env, callback);
return C_SetCallback(_SourceCallBack);}
static int _SourceCallBack(int length, char *pBuf) {
//这个方法是C++中回调方法,在这里将数据回调给Java
JNIEnv *jniEnv;
int state = (*gJavaVM)->GetEnv(gJavaVM, (void**)&jniEnv, JNI_VERSION_1_6);
if (state !=JNI_OK) {
(*gJavaVM)->AttachCurrentThread(gJavaVM, &jniEnv, NULL);
}
jbyteArray data = (*jniEnv)->NewByteArray(jniEnv, length);
//copy bytes from *byte to jbyteArray
(*jniEnv)->SetByteArrayRegion(jniEnv, data, 0, length, pBuf);
jclass playerCallbackCls = (*jniEnv)->GetObjectClass(jniEnv, jSourceCallback);
//call java method
jmethodID sendState = (*jniEnv)->GetMethodID(jniEnv, playerCallbackCls, "onCallback",
"([B)V");
(*jniEnv)->CallVoidMethod(jniEnv, jSourceCallback, sendState, data);
(*jniEnv)->DeleteLocalRef(jniEnv, data);
(*jniEnv)->DeleteLocalRef(jniEnv, playerCallbackCls);
return 0;
}
JNIEXPORT jint JNICALL Java_com_native_Release
(JNIEnv *env, jobject obj) {
//不需要使用的时候,不要忘记释放全局引用
(*env)->DeleteGlobalRef(env, jSourceCallback);
(*gJavaVM)->DetachCurrentThread(*gJavaVM);
(*gJavaVM)->DestroyJavaVM(gJavaVM);
return 0;}
这里展示了jni回调Java的流程,首先初始化将Java回调函数对象传入保存,然后为C++实现回调函数,
内部逻辑会先jni中声明的回调函数,然后在C回调函数中使用回调函数对象回调java函数。
最后清除全局引用。
将实际代码保存下来作为参考。
见过好多类似的直接在设置回调的jni方法那里就回调Java函数,不知道这种回调有什么作用。。。