接着上一节,这一节来写一下如何用本地代码调用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);
}