1. 程式人生 > >jni回撥Java方法

jni回撥Java方法

/**
 * 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函式,不知道這種回撥有什麼作用。。。