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);


}

获取项目代码

你可能感兴趣的:(JNI心得)