本站文章均为 李华明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" ); }

运行截图:

更多相关文章

  1. C语言函数的递归(上)
  2. (二) RIL 层分析
  3. Android(安卓)的网络编程(3)-HttpURLConnection接口
  4. 旋屏时,OnCreate方法重复调用的解决
  5. Android(安卓)Matrix Riot (IM)SDK 集成专栏(登录注册)
  6. 采用回调Activity的形式创建AlertDialog单选列表框
  7. Android(安卓)数据Parcel序列化过程源码分析
  8. imageView中图片各种比例类型的显示方式的参数设置
  9. 2011年Android(安卓)Binder机制学习笔记之一

随机推荐

  1. 列表类型内置方法
  2. 变量的三个特征
  3. 字符串类型内置方法
  4. 牛气的JavaScript,让雪花算法成为空气
  5. 工作累了,用java写个游戏吧!开源一款游戏引
  6. Python2和3字符编码的区别
  7. Java如何获取方法参数具体名称?这是个好问
  8. Java线程池「异常处理」正确姿势:有病就得
  9. 一些好用的Java小库儿
  10. 数字类型内置方法