首页 > 编程语言 >【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!

【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!

时间:2022-11-25 14:06:45浏览次数:71  
标签:cocos2dx 函数 示例 int getStaticMethodInfo 调用 minfo 参数 Android

本站文章均为​ 李华明Himi ​​原创,转载务必在明显处注明


很多看过之前Himi的​​【iOS-cocos2d-X 游戏开发之七】整合Cocos2dX的Android项目到Xcode项目中,Xcode编写&编译代码,Android导入打包运行即可!​​ 博文的童鞋都在问我如何在Xcode中能调用Java的函数,比如在Android端需要加入广告、支付、等第三方平台或者单独处理的一些代码;那么本篇Himi分享如何在Cocos2dx中访问调用Android的Java层函数;

首先Himi大概的介绍一个类 JniHelper ;

此类主要用于Jni与Java层之间的相互访问的作用,那么此类的常用的一些函数这里首先介绍下,否则直接上代码不太容易吸收 ;

JniHelper 类常用函数:

 1.  getStaticMethodInfo    (四个参数,bool 返回值)

使用示例代码:


​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中先导入如下头文件:


​//使用预编译,对当前平台为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.无参数,无返回值---------------------------------$$$$$$-----------------------------​


​#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.无参数,无返回值​


​public​​ ​​static​​ ​​void​​ ​​testFun() {​


​Log.e(​​ ​​"Himi"​​ ​​, ​​ ​​"静态函数示例1.无参数,无返回值"​​ ​​);​


​}​


运行截图:

​​

 

示例代码段2:

Xcode 代码:


​//静态函数示例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) 代码:


​// 静态函数示例2.有参数,无返回值​


​public​​ ​​static​​ ​​void​​ ​​testFunWithInt(​​ ​​int​​ ​​_int) {​


​Log.e(​​ ​​"Himi"​​ ​​, ​​ ​​"静态函数示例1.有参数,无返回值;传入的参数int="​​ ​​+ _int);​


​}​


运行截图:

  ​​​

示例代码段3:

Xcode 代码:



​//静态函数示例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) 代码:


​// 静态函数示例3.有参数,有返回值​


​public​​ ​​static​​ ​​int​​ ​​testFunWithIntAndRtn(​​ ​​int​​ ​​_int) {​


​Log.e(​​ ​​"Himi"​​ ​​, ​​ ​​"静态函数示例1.有参数,有返回值;传入的参数int="​​ ​​+ _int);​


​return​​ ​​_int+​​ ​​1000​​ ​​;​


​}​



运行截图:

  ​​​

示例代码段4:

Xcode 代码:

 


​#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) 代码:

 


​// 静态函数示例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 代码:



​#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 代码:

 


​//---- 函数示例之非静态函数调用​


​//(先获取个对象)​


​public​​ ​​static​​ ​​Activity actInstance;​​ ​​//定义单例​


​public​​ ​​static​​ ​​Object rtnActivity() {​


​return​​ ​​actInstance;​


​}​


​//使用此对象进行调用非静态函数​


​public​​ ​​void​​ ​​nostaticFun() {​


​Log.e(​​ ​​"Himi"​​ ​​, ​​ ​​"no static Function is OK - By Himi"​​ ​​);​


​}​



运行截图:


  ​​​



标签:cocos2dx,函数,示例,int,getStaticMethodInfo,调用,minfo,参数,Android
From: https://blog.51cto.com/xiaominghimi/5886622

相关文章