【Cocos2d入门教程十四】Cocos2d-x与Java的通讯

Cocos2d-x与Java的通讯,听起来有点悬乎。其实本质上就是JNI的调用。首先我们先来看一下JNI是什么。

一.JNI简介

1.是什么?

JNIJava 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()

(2) 非静态方法调用:GetMethodInfo()

两者都为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类


1.建立JNI类并且建立静态方法fun
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调用

注意:C++端调用需要引入头文件

#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的回调

关于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的通讯就介绍到这里,有讲得不对的地方还望指出进行探讨互相学习!

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...