minfo.env->CallVoidMethod(activityObj, minfo.methodID);方法把对象和要调用的方法以及参数(如果有
)传递个java类对象中的非静态方法;
java类:
// c++中 用的方法
public static Object rtnActivity() {
System.out.println("----------rtnActivity");
return mainActivity;
}
public void showAD() {
Log.i("test", "jnihelper do ...show ad");
// ad
// 展示插播广告,可以不调用loadSpot独立使用
SpotManager.getInstance(MainActivity.this).showSpotAds(
MainActivity.this, new SpotDialogListener() {
@Override
public void onShowSuccess() {
Log.i("SpotAd", "展示成功");
}
@Override
public void onShowFailed() {
Log.i("SpotAd", "展示失败");
}
});
}
红色部分替换成你要展示的广告即可
c++调用cpp:
//判断当前是否为Android平台;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
//定义Jni函数信息结构体;
JniMethodInfo minfo;
//返回一个bool值表示是否找到此函数;
bool isHave = JniHelper::getStaticMethodInfo
(minfo,"org/cocos2dx/hellocpp/MainActivity","rtnActivity", "()Ljava/lang/Object;");
jobject activityObj;
if (isHave) {
//CallStaticObjectMethod调用java函数,并把返回值赋值给activityObj
activityObj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);
}
//2. 查找displayWebView接口,获取其函数信息,并用jobj调用;
//定义Jni函数信息结构体;
isHave = JniHelper::getMethodInfo(minfo,"org/cocos2dx/hellocpp/MainActivity","showAD",
"()V");
if (!isHave)
{
CCLog("jni:showAD 函数不存在;");
}
else
{
//调用displayWebView函数,并传入参数
minfo.env->CallVoidMethod(activityObj, minfo.methodID);
}
#endif
对于要调用带参数的java非静态方法的可参见分割线一下部分
-----------------华丽的分割线---------------------------------------------
主体思路
通过JNI获取java虚拟机,再获取当前程序的JNI环境,通过JNI环境获取需要调用的java类信息,再获取需要调用的java类中的函数信息。再通过JNI环境调用,使用类信息、函数信息,调用对应的java函数。
看起来好像有点复杂,but不用担心,cocos2d-x中有一个JniHelper类(头文件的copyright为:cocos2d-x.org,是Google提供的还是cocos2d-x小组自己封装的我就不清楚了),它已经把这些工作封装好了。
JniHelper类的使用
加入如下头文件:
#include "platform/android/jni/JniHelper.h"
需要使用的接口如下:
static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
实现上我们只需要使用上面这两个接口,就可以获取java类的所有函数信息了。JNI环境的获取、各种错误处理都已经在这两个接口实现中封装好了。
先上代码,再来依次讲解每个参数的意义和使用方法:
//函数信息结构体
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,/*JniMethodInfo的引用*/
"com/omega/MyApp",/*类的路径*/
"getJavaActivity",/*函数名*/
"()Ljava/lang/Object;");/*函数类型简写*/
jobject activityObj;
if (isHave)
{
//CallStaticObjectMethod调用java函数,并把返回值赋值给activityObj
activityObj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);
}
OK,很简单。上面的代码,就是使用JNI在C++中调用java类静态函数的典型使用方法。只有两步:
1. 获取java函数的信息,classid、methodid等等
2. 选择JNIEnv中的接口,进行函数调用
getStaticMethodInfo参数详解
两个接口的参数一样,意义也相同,详解如下:
JniMethodInfo &methodinfo JniMethodInfo对象的引用,函数执行中会把jniEvn、classid、methodid写入到引用中。
const char *className 类的路径,把类的完整包名写全,用法如以上代码。
const char *methodName 函数名,函数名写上就行了。
const char *paramCode 函数类型简写
这个参数需要单独介绍,它的格式为:(参数)返回类型。
例如:无参数,void返回类型函数,其简写为 ()V
java中的类型对应的简写如下:
参数类型 参数简写
boolean Z
byte B
char C
short S
int I
long J
float F
double D
void V
Object Ljava/lang/String; L用/分割类的完整路径
Array [Ljava/lang/String; [签名 [I
多参数的函数
如果函数有多个参数,直接把简写并列即可。注意Object与Array型参数简写结尾的分号,示例:
IIII //4个int型参数的函数
ILjava/lang/String