Cocos2d-x学习之通过Jni调用Android的Java层代码


转载自【黑米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 返回值)

使用示例代码:

boolisHave = 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值表示是否找到此函数
    boolisHave = 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.无参数,无返回值
publicstatic void testFun() {
    Log.e("Himi","静态函数示例1.无参数,无返回值");
}

运行截图:

示例代码段2:

Xcode 代码:

//静态函数示例2.有参数,无返回值------------------------------$$$$$$$--------------------------------
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台
    JniMethodInfo minfo;//定义Jni函数信息结构体
    //getStaticMethodInfo 次函数返回一个bool值表示是否找到此函数
    boolisHave = 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.有参数,无返回值
publicstatic 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值表示是否找到此函数
 
boolisHave = 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;
    boolisHave = 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.有参数,有返回值
publicstatic 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值表示是否找到此函数
    boolisHave = 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类型)
publicstatic 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值表示是否找到此函数
    boolisHave = 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 代码:

//---- 函数示例之非静态函数调用
//(先获取个对象)
publicstatic Activity actInstance;//定义单例
publicstatic Object rtnActivity() {
    returnactInstance;
}
//使用此对象进行调用非静态函数
publicvoid nostaticFun() {
    Log.e("Himi","no static Function is OK - By Himi");
}

运行截图:

 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值