持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
前些日子刚刚解决了Java调用C++代码的中间键搞定,这不,又有新的功能了,还要在写so文件,其实我的内心十分的吐槽,左一个右一个的,直接用java写不香吗,搞的C++程序员还得写个中间键,哎!就当自己多了项技能吧!
今天我们就来讲述下如何JAVA在调用so文件时,如何实现类似于C++回调的方法吧!
对于回调,C++程序员应该都不陌生吧!
回调函数就是一个通过函数指针调用的函数。如果你把函数指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数
在纯C++类中实现回调方法不是很难,那么,在JNI中让Android调用时,中间出现了回调该怎么使用呢?
C++中回调函数的调用方式:
定义一个回调函数
typedef void (*CallBackFun)(int nData1, std::string sData2);
定义回调函数
CallBackFun m_pCallBackFun;
在使用类中注册该函数
void SetCallOperation(CallBackFun fun)
{
m_pCallBackFun = fun
}
上述内容完成后我们就可以使用回调函数传递信息了。
根据C++中的回调方式,让我们的Android程序也能实现类似C++中的回调。
在JNI文件中,定义两个类指针:
JNIEnv *mJni;
jobject mJobject;
当我们自动生成动态接口函数时,会发现,生成的函数接口中,默认会带有两个参数,第一个参数就是JNIEnv,第二个参数就是jobject。其次才是我们函数中有效的参数。
在Native中不存在回调的方法,在JNI文件中的回调只是Native调用JAVA函数的方法。
最终的调用形式,如下所示:
jmethodID mid = mJni->GetMethodID(cls, "CallBackFunAndroidBack", "(ILjava/lang/String;)V");
mJni->CallVoidMethod(mJobject, mid, 参数1,参数2);
使用上述两句代码就可以让JAVA函数接收我们传入的参数了。
在这里需要注意以下几个方面:
1:GetMethodID中传入的函数名一定与JAVA环境中调用的函数名保持一致。
2:书写参数时一定要记得使用JAVA自身系统的类时,例如:String类,必须配备";"否则会出现错误。我在开发过程中写的参数较多,一时之间忘记了最后一个分号。导致Android调用总是出现问题,还调试了很长时间。这都是教训呀!
3:在使用JNI自带的CallVoidMethod时,一定要分情况而言,该函数只能传递返回值为void类型的回调
4:回调函数中有多少个参数,JNI的回调类中必须要写全!
以上就实现了简单的参数回调了,那么对于一些复杂的传参来说,比如:需要给Android传入一个类似于std::vector<结构体> 的数据,该如何进行回调呢?这个功能有一些繁琐,下一篇文章我们进行更新哟~
先尝试下这个简单的功能吧!
我是中国好公民st,一名C++开发程序猿~