【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!
本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/android-game/725.html ☞ 点击订阅 ☜ 本博客最新动态!及时将最新博文通知您!
很多看过之前Himi的【iOS-cocos2d-X 游戏开发之七】整合Cocos2dX的Android项目到Xcode项目中,Xcode编写&编译代码,Android导入打包运行即可! 博文的童鞋都在问我如何在Xcode中能调用Java的函数,比如在Android端需要加入广告、支付、等第三方平台或者单独处理的一些代码;那么本篇Himi分享如何在Cocos2dx中访问调用Android的Java层函数;
首先Himi大概的介绍一个类 JniHelper ;
此类主要用于Jni与Java层之间的相互访问的作用,那么此类的常用的一些函数这里首先介绍下,否则直接上代码不太容易吸收 ;
JniHelper 类常用函数:
1. getStaticMethodInfo (四个参数,bool 返回值)
使用示例代码:
1 | bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFun" , "()V" ); |
此函数主要用于获取Java定义的类静态函数是否存在,返回bool;
此函数有3个参数:
第一参数: minfo ->JniMethodInfo 类型,后面详细说;
第二个参数:类的路径。
第三个参数:方法名(第一参数类中的函数)
第四个参数:(参数)返回类型
关于第一个和第二个参数都比较容易理解,那么第三个参数需要重点介绍一下;例如你在Java中定义一个如下函数 public void helloJni(){};
那么getStaticMethodInfo函数第三个参数你应该传入 “()V” 表示此函数无参无返回值!
如果有这么一个函数: public int helloJni(int _int){return 823};
那么getStaticMethodInfo函数第三个参数你应该传入 “(I)I” 表示此函数需要传入一个int类型的参数并且返回一个int类型!
大概说两个童鞋们应该基本理解了,那么下面详细写一些对照表,留给大家对照;
参数、返回值样式对照表:
这里的签名指的就是getStaticMethodInfo函数第三个参数中传入的样式;
2. getMethodInfo 类似与第一个函数,只是对应非静态函数;此函数主要用于获取Java定义的类非静态函数是否存在,返回bool;
JniMethodInfo 类:
此类型主要用户保存类结构体,可以通过JniHelper类的getStaticMethodInfo函数实例化JniMethodInfo对象,从而使用实例的env属性调用CallStaticVoidMethod,CallVoidMethod,CallStaticIntMethod等函数进行对保存的类结构调用函数;
常用的函数如下:(静态系列函数)
1. CallStaticVoidMethod(classID,methodID);
2. CallStaticIntMethod(classID,methodID);
3~(n-1) ……省略掉,童鞋们一看就明白;
n. CallStaticObjectMethod(classID,methodID);
带参数的函数:(如int类型)
CallStaticVoidMethod(classID,methodID,int _int);
非静态系列函数:
1. CallVoidMethod(jobj,methodID);
2. CallIntMethod(jobj,methodID);
3~(n-1) ……省略掉,童鞋们一看就明白;
n. CallStaticObjectMethod(jobj,methodID);
带参数的函数:(如int类型)
CallVoidMethod(classID,methodID,int _int);
这里讲解下几个参数函数:
1. classID: 类ID , JniMethodInfo 对象包含此属性;
2. methdID: 方法ID,JniMethodInfo 对象也包含此属性;
3. jobj : java中Object类型,如自定义类,String…
非静态函数调用的时候,需要的是对象,所以与静态函数调用的第一个参数不同;
那么既然能调用Java的函数,那就能得到函数返回值,但是这里我们得到的返回值书写类型如下:
譬如返回int 类型,在Xcode中使用 jint 这种形式,更多形式如下:
int -> jint
…省略,大家一看就懂得;
object -> jobject
估计有的童鞋已经晕了,没关系,下面Himi写了一些例子代码,结合来看就一目了然啦。
Xcode中先导入如下头文件:
1 2 3 4 5 6 7 | //使用预编译,对当前平台为Android时才会导入如下头文件 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include <jni.h> #include "platform/android/jni/JniHelper.h" #include <android/log.h> #endif |
示例代码段1:
Xcode 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ////静态函数示例1.无参数,无返回值---------------------------------$$$$$$----------------------------- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台 JniMethodInfo minfo; //定义Jni函数信息结构体 //getStaticMethodInfo 次函数返回一个bool值表示是否找到此函数 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFun" , "()V" ); if (!isHave) { CCLog( "jni:此函数不存在" ); } else { CCLog( "jni:此函数存在" ); //调用此函数 minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID); } CCLog( "jni-java函数执行完毕" ); #endif |
Android(Java) 代码:
1 2 3 4 | // 静态函数示例1.无参数,无返回值 public static void testFun() { Log.e( "Himi" , "静态函数示例1.无参数,无返回值" ); } |
运行截图:
示例代码段2:
Xcode 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //静态函数示例2.有参数,无返回值------------------------------$$$$$$$-------------------------------- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台 JniMethodInfo minfo; //定义Jni函数信息结构体 //getStaticMethodInfo 次函数返回一个bool值表示是否找到此函数 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFunWithInt" , "(I)V" ); if (!isHave) { CCLog( "jni:此函数不存在" ); } else { CCLog( "jni:此函数存在" ); //调用此函数 minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,823); } CCLog( "jni-java函数执行完毕" ); #endif |
Android(Java) 代码:
1 2 3 4 | // 静态函数示例2.有参数,无返回值 public static void testFunWithInt( int _int) { Log.e( "Himi" , "静态函数示例1.有参数,无返回值;传入的参数int=" + _int); } |
运行截图:
示例代码段3:Xcode 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | //静态函数示例3.有参数,有返回值--------------------------------$$$$$$$-------------------------------- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台 JniMethodInfo minfo; //定义Jni函数信息结构体 //getStaticMethodInfo 次函数返回一个bool值表示是否找到此函数 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFunWithIntAndRtn" , "(I)I" ); jint _int ; if (!isHave) { CCLog( "jni:此函数不存在" ); } else { CCLog( "jni:此函数存在" ); //调用此函数 _int = minfo.env->CallStaticIntMethod(minfo.classID, minfo.methodID,823); //尝试jint是否能正常接收返回的int值 JniMethodInfo minfo_ty; bool isHave = JniHelper::getStaticMethodInfo(minfo_ty, "com/ai/ommr/OhMonsterMR4Android" , "testFunWithInt" , "(I)V" ); if (isHave) { minfo_ty.env->CallStaticVoidMethod(minfo_ty.classID, minfo_ty.methodID,_int); } } CCLog( "jni-java函数执行完毕" ); #endif |
Android(Java) 代码:
1 2 3 4 5 | // 静态函数示例3.有参数,有返回值 public static int testFunWithIntAndRtn( int _int) { Log.e( "Himi" , "静态函数示例1.有参数,有返回值;传入的参数int=" + _int); return _int+ 1000 ; } |
运行截图:
示例代码段4:Xcode 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台 JniMethodInfo minfo; //定义Jni函数信息结构体 //getStaticMethodInfo 次函数返回一个bool值表示是否找到此函数 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , "testFunWithStringAndRtn" , "(I)Ljava/lang/String;" ); jobject jobj; if (!isHave) { CCLog( "jni:此函数不存在" ); } else { CCLog( "jni:此函数存在" ); //调用此函数 jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID,823); } CCLog( "jni-java函数执行完毕" ); #endif |
Android(Java) 代码:
1 2 3 4 5 | // 静态函数示例4.有参数,有返回值(String类型) public static String testFunWithStringAndRtn( int _int) { Log.e( "Himi" , "静态函数示例4.有参数,有返回值(String类型);int=" + _int); return "yes,return 'String' is OK --by Himi" ; } |
运行截图:
示例代码段5:Xcode 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台 JniMethodInfo minfo; //定义Jni函数信息结构体 //getStaticMethodInfo 次函数返回一个bool值表示是否找到此函数 bool isHave = JniHelper::getStaticMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , //类的路径 "rtnActivity" , //方法名 "()Ljava/lang/Object;" ); //括号里的是参数,后面的是返回值。 jobject jobj; if (isHave) { jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID); } CCLog( "正确获取到 jobj" ); // isHave = JniHelper::getMethodInfo(minfo, "com/ai/ommr/OhMonsterMR4Android" , //类的路径 "nostaticFun" , //方法名 "()V" ); //括号里的是参数,后面的是返回值。 if (isHave) { minfo.env->CallVoidMethod(jobj, minfo.methodID); } CCLog( "jni-java函数执行完毕" ); #endif |
Java 代码:
1 2 3 4 5 6 7 8 9 10 | //---- 函数示例之非静态函数调用 //(先获取个对象) public static Activity actInstance; //定义单例 public static Object rtnActivity() { return actInstance; } //使用此对象进行调用非静态函数 public void nostaticFun() { Log.e( "Himi" , "no static Function is OK - By Himi" ); } |
运行截图:
更多相关文章
- C语言函数的递归(上)
- (二) RIL 层分析
- Android(安卓)的网络编程(3)-HttpURLConnection接口
- 旋屏时,OnCreate方法重复调用的解决
- Android(安卓)Matrix Riot (IM)SDK 集成专栏(登录注册)
- 采用回调Activity的形式创建AlertDialog单选列表框
- Android(安卓)数据Parcel序列化过程源码分析
- imageView中图片各种比例类型的显示方式的参数设置
- 2011年Android(安卓)Binder机制学习笔记之一