JNI心得 - (四)C++ 調用 java函數

獲取代碼

接着上一節,這一節來寫一下如何用本地代碼調用java函數。首先在MainActivity.java聲明一個本地方法

    public static native void callBack(MainActivity activity);

然後將生成的代碼移到cpp文件中

JNIEXPORT void JNICALL Java_com_example_test_jnitest_MainActivity_callBack
        (JNIEnv *env, jobject,jobject mainActivity){
    
}

上面有一個jobject類型的參數,這個參數是自動生成的,如果這個函數是非static的則這個參數位置就是jobject類型的,代表調用此函數的類的實例的引用,如果這個函數是靜態的則這個位置大參數類型爲jclass,代表調用此函數的類的引用。出於方便我們就調用MainActivity的函數,在MainActivity.java 加一個供調用的函數

    void onCallBack(int flag){
        Log.i(TAG, "onCallBack: "+flag);
    }

一切就緒,接下來就來看看如何在jni層實現調用

首先根據參數mainActivity 來獲取java的class類.jni層用jclass表示java的class

    jclass  mainClass = env->GetObjectClass(mainActivity);

然後再根據mainClass來獲取jmethodID,jmethodID表示java方法

    jmethodID  jmethodID1 = env->GetMethodID(mainClass,"onCallBack","(I)V");

GetMethodID()裏參數的意思是在mainClass所代表的類裏面找到一個名叫onCallBack的函數他只有一個int類型的參數,他的返回值值是void.

 

獲取到methodId之後就可以調用javac函數了

    env->CallVoidMethod(mainActivity,jmethodID1,101);

調用之後還要delete掉本地對象,因爲jni的申請本地對象資源是有限的,所以要儘量在本地對象不用的時候delete掉,以便節省資源。

    env->DeleteLocalRef(mainClass);

完整代碼如下

JNIEXPORT void JNICALL Java_com_example_test_jnitest_MainActivity_callBack
        (JNIEnv *env, jobject,jobject mainActivity){

    jclass  mainClass = env->GetObjectClass(mainActivity);


    if(mainClass == nullptr)
        return ;
    jmethodID  jmethodID1 = env->GetMethodID(mainClass,"onCallBack","(I)V");

    if(jmethodID1 == nullptr)
        return;

    env->CallVoidMethod(mainActivity,jmethodID1,101);

    env->DeleteLocalRef(mainClass);


}

獲取項目代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章