Cocos2d-x与Java的通讯,听起来有点悬乎。其实本质上就是JNI的调用。首先我们先来看一下JNI是什么。
一.JNI简介
1.是什么?
JNI是Java Native Interface的缩写,它提供了若干的API实现了JAVA和其他语言的通信
2.好处:
与其他语言相互调用。
与本地已编译的代码交互
二Cocos下的JNI
cocos2d-x引擎对jni的操作进行了封装,提供了一个非常好用的类:JniHelper,定义了一些常用的接口
cocos3.0版本以上此类位于引擎目录/cocos/platform/android/jni/JniHelper.h目录下
三 Cocos下JNI的调用
1.基本数据类型对应表:
注意:String类型与Object类型为引用数据类型 以L开头 以;结尾 中间为引用路径
2.主要方法
(1)静态方法调用:GetStaticMethodInfo()
两者都为4个参数:第一参数为对象,第二参数为JNI类所在位置,第三参数为JNI类的方法名,第四参数为JNI调用的方法类型签名
调用的步骤主要分为Java端与C++端(Cocos端)
Java端主要负责写好被调用接口
C++端用于JNI调用Java端
现在开始进行Java端的实现
设计思路:
(1)Java端在src下的org.cocos2dx.cpp下建立JNI类
(2) 在JNIConnect 建立静态方法fun()
(3)AppActivity.java初始化JNI类
public classJNIConnect { privatestatic ContextmyContext; //通信的接口 activety传进来 staticvoid init(Context context) { myContext=context; } publicstatic void fun() { System.out.println(“我是静态"); } }2.在AppActivity下我重载onCreate( )方法用于初始JNI类
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); JNIConnect.init(this); }
Ok Java端接口完成
现在开始进行C++端的实现JNI调用
#include"platform/android/jni/JniHelper.h”
设计思路:
1.建立JniMethodInfo对象
2.调用getStaticMethodInfo将对象传到org/cocos2dx/cpp/JNIConnect下的void类型的fun静态方法
第一个参数放置JNIMethodInfo对象,第二参数主要放置JNI类的路径,第三参数主要写入JNI调用方法名,第四参数为JNI调用方法类型
3.根据JNI类ID、方法ID将这个对象返回接收
<span style="font-size:12px;">JniMethodInfo infos; JniHelper::getStaticMethodInfo(infos,"org/cocos2dx/cpp/JNIConnect",”fun","()V"); JniHelper::getEnv()->CallStaticVoidMethod(infos.classID,infos.methodID);</span>注意getStaticMethodInfo()与CallStaticVoidMethod()是JNI的调用与回调,它们都属于调用和回调静态类型
这是Cocos2d下利用JNI静态调用来进行与Java的通讯。接下来看下如何实现调用的时候进行传参
四JNI的传参
JNI调用传递单个参数
Java端的实现
public static void testStaticCall(int num) { Stringstr ="num:"+num; System.out.println(str); }C++端的实现
JniMethodInfo_ infos; JniHelper::getStaticMethodInfo(infos,"testStaticCall","(I)V"); int num =123; JniHelper::getEnv()->CallStaticVoidMethod(infos.classID,infos.methodID,num);注意:传参需要注意的是签名,int类型的签名为I 写在调用方法的第四参数里
有时候Cocos下与Java进行通讯时传递单参数可能会满足不了需要,我们来继续学习如何进行JNI的多参数传递
Java端的实现
public static void testStaticCall(intnum,String str) { StringnewStr=str+":"+num; System.out.println(newStr); }
C++端的实现
JniMethodInfo_ infos; JniHelper::getStaticMethodInfo(infos,"(ILjava/lang/String;)V"); int num =123; jobject str=infos.env->NewStringUTF("helloworld"); JniHelper::getEnv()->CallStaticVoidMethod(infos.classID,num,str);注意:String类型签名后面要紧跟分号,多参数传递签名之间在第四参数里不需要逗号隔开
我们已经学会了JNI调用中的传参,有传参相对应可能有返回值,没错,接下来是知识点就是JNI的回调
关于JNI的回调 本章以int类型的回调和String类型两种比较经典的回调类型进行讲解,我们先来看一下int类型的回调
Java端的实现:
public static int fun1() { return1+1; }C++端的实现:
JniMethodInfo_ infos; JniHelper::getStaticMethodInfo(infos,”fun1","()I"); jint num=JniHelper::getEnv()->CallStaticIntMethod(infos.classID,infos.methodID);注意:JNI回调需要注意的为CallStaticIntMethod() 。作用是返回Int类型,并且需要用jni类型进行接收,int用jint接收,String用jstring接收等等
JNI调用中的int类型回调已经Ok。接下来我们来看一下比int类型稍复杂一点的String类型回调
String类型接收步骤:
1.强制转类型
2.使用封装的jni类进行转格式
3.使用c++的接收
Java端的实现:
<span style="font-size:12px;">public static String testStaticCall() { return "HelloWorld"; }</span>
C++端的实现:
JniMethodInfo_ infos; JniHelper::getStaticMethodInfo(infos,"()Ljava/lang/String;"); jstring text =(jstring)JniHelper::getEnv()->CallStaticObjectMethod(infos.classID,infos.methodID); std::string str=JniHelper::jstring2string(text); log("%s",str.c_str());
关于Cocos2d与Java的通讯就介绍到这里,有讲得不对的地方还望指出进行探讨互相学习!