C++ 调用 Java Cocos2d-x利用jni调用java层代码

     JNI 是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)所以我们需要引用JNI头文件。(引入前做一下平台判断)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

#include <jni.h>
#include
"platform/android/jni/JniHelper.h"
#include
<android/log.h>

#endif

     在 c++项目路径下cocos2d/cocos/platform/android/jni中的JniHelper.cpp就是cocos为我们封装的Jni接口。里面实现了调用Java内容的方法。 
  在helloworld类中调用静态方法
// 调用Java中的静态方法
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)     
     JniMethodInfo info;// 声明一个结构体变量,结构体 JniMethodInfo在导入文件类中已实现
     bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/cpp/TestJni","func1","()V”);// 得到Java类中func1方法
参数:新建类的路径(在pro.android/src/org/..)、方法名、参数列表返回值类型
     if (!isHave) {
     CCLOG(" 此函数不存在 ");
     }else{
     CCLOG("
此函数存在 ");
     minfo.env->CallStaticVoidMethod(minfo.classID,minfo.methodID);
     }
     CCLOG("此函数执行完毕");
     #endif

// 调用Java中的非静态方法
首先要考虑新建一个类,因为要调用非静态方法,所以应当使用单例设置模式
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    JniMethodInfo minfo1;
    bool isHave = JniHelper::getStaticMethodInfo(minfo1, "org/cocos2dx/cpp/TestJniHelper" , "getObj" , "()Ljava/lang/Object;" );
    jobject jobs;// object为封装好的对象
    if (!isHave) {
        CCLOG(
" 此函数不存在 " );
    }
else {
        CCLOG(
" 此函数存在 " );
       
// 获取对象
        jobj = minfo1.env->CallStaticObjectMethod(minfo1.classID,minfo1.methodID);
    }
   
bool re = JniHelper::getMethodInfo(minfo1, "org/cocos2dx/cpp/TestJniHelper" , "func" , "()V" );
   
if (re) {
        minfo1.env->CallVoidMethod(jobj,minfo1.methodID);
    }
else {
        CCLOG(
" 此函数不存在 " );
    }
    CCLOG( " 此函数执行完毕 " );
#endif
其中参数与返回值类型的对应表如下:


     如何在Xcode中能调用Java的函数,比如在Android端需要加入广告、支付、等第三方平台或者单独处理的一些代码;本文讲解如何在Cocos2dx中访问调用Android的Java层函数;
首先介绍一个类 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 中先导入如下头文件:
1
2
3
4
5
6
7
// 使用预编译,对当前平台为Android时才会导入如下头文件
 
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include &lt;jni.h&gt;
#include "platform/android/jni/JniHelper.h"
#include &lt;android/log.h&gt;
#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 -& gt ; 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 -& gt ; 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 -& gt ; 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 -& gt ; 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 -& gt ; 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 -& gt ; CallStaticObjectMethod ( minfo . classID ,   minfo . methodID );
     }
     CCLog ( " 正确获取到 jobj" );
 
     //
     isHave = JniHelper :: getMethodInfo ( minfo ,
                                                 "com/ai/ommr/OhMonsterMR4Android" ,    // 类的路径
                                                 "nostaticFun" ,    // 方法名
                                                 "()V" );    // 括号里的是参数,后面的是返回值。  
 
     if   ( isHave )   {
         minfo . env -& gt ; 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" );
}
运行截图:
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值