Cocos文档-Java原生反射机制
如何在 Android 平台上使用 JavaScript 直接调用 Java 方法 · Cocos Creator
Cocos文档-JSB使用指南
JSB 2.0 使用指南 · Cocos Creator
https://docs.cocos.com/creator/manual/zh/advanced-topics/JSB2.0-learning.html
一 Cocos中调用Android方法
二 Android中调用Cocos方法
三 传递JSON数据
四 监听返回键
五 遇到的问题
cocos和android的互相调用,在Java中可以调用TypeScript的方法,在TypeScript中可以调用Java的方法。
![](https://img-blog.csdnimg.cn/img_convert/76cba22d6d2e57837d63f61c056885f9.png)
一 Cocos中调用Android方法: jsb.reflection.callStaticMethod
通过反射机制直接在 JavaScript 中调用 Java 的静态方法。
反射机制:Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
在android的AppActivity中定义一个方法
![](https://img-blog.csdnimg.cn/img_convert/240b0553429498775512a5d9f1a7aed5.png)
在cocos中调用Android定义的方法,传递参数hello。
start(){
let result = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "AndroidFun", "(Ljava/lang/String;)Ljava/lang/String;", "hello");
}
运行android项目,可以看到调用成功
![](https://img-blog.csdnimg.cn/img_convert/92566bf46af2714e6ae28f59ae5f4445.png)
二 Android中调用Cocos的方法:Cocos2dxJavascriptJavaBridge.evalString
在Cocos的MainScene.ts中定义方法
![](https://img-blog.csdnimg.cn/img_convert/4d5c9cafd4e2eed8e71ed1579766ccf6.png)
MainScene.ts需要赋值给cc,不然android访问不到这个方法,这段代码必须放在android调用cocos方法之前,可以游戏初始化时执行这段代码。
![](https://img-blog.csdnimg.cn/img_convert/216d455fe637f3f0a3479d0518383571.png)
目前引擎并未承诺多线程下的安全性,所以在开发过程中需要避免 JS 代码在其他线程被调用,以避免各种内存错误,一定要在 GL 线程中执行。
android调用cocos方法。
org.cocos2dx.lib.Cocos2dxHelper.runOnGLThread(new Runnable() {
@Override
public void run() {
org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge.evalString("cc["MainScene"].CocosFun("abc")");
}
});
运行项目,可以看到android已经成功调用了cocos的方法,并输出了调试信息
![](https://img-blog.csdnimg.cn/img_convert/6b55b0294cb711fbb8a45e1ad31a0a7c.png)
三 传递JSON数据
原生和cocos的互相传递json消息,因为json可以自定义各种数据,比较方便。
![](https://img-blog.csdnimg.cn/img_convert/6626a954318e92d50c743930a2df65b5.png)
Cocos中派发和接收Android的消息
MainScene.ts:
/**
* 发送消息到安卓
* @param data object(json格式)
*/
public static postMessageToAndroid(data) {
let str = JSON.stringify(data);
console.log("[MainScene] postMessageToAndroid:", str);
let result = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "revJsMessage", "(Ljava/lang/String;)Ljava/lang/String;", str);
}
/**
* 接收来自安卓的原生消息
* @param data json格式字符串
*/
public static revAndroidMsg(data) {
let json = JSON.parse(data);
let cmd = json.cmd;
switch (cmd) {
case 1001:
console.log("[MainScene] revAndroidMsg:", cmd, json.msg);
break;
}
}
Android中派发和接收Cocos消息
android中的json使用JsonObject,jsonObject.toString()将json转成字符串后通过evalString接口传递。
传递的json数据需要用replace(""", "\"")特殊处理,将原本{"cmd":1001,"msg":"I'm Android"} 字符串转成 {"cmd":1001,"msg":"I'm Android"},通过转义字符来处理引号""嵌套导致的问题。
AppActivity.java:
/**
* 发送消息给JS
* @param data JSONObject格式消息
*/
public static void postMessageToJs(final JSONObject data){
org.cocos2dx.lib.Cocos2dxHelper.runOnGLThread(new Runnable() {
@Override
public void run() {
String str = data.toString();
str = str.replace(""", "\"");
Log.v("v","[Android] postMessageToJs:" + str);
org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge.evalString("cc["MainScene"].revAndroidMsg("" + str + "")");
}
});
}
/**
* 接收来自JS的消息
* @param data json格式字符串
* @return 返回数据
*/
public static String revJsMessage(String data) {
Log.v("v","[Android] revJsMessage:" + data);
try{
JSONObject revObj = new JSONObject(data);
int cmd = revObj.getInt("cmd");
switch (cmd){
case 1001:
//打印收到的JS消息
String msg = revObj.getString("msg");
Log.v("v","[Android] revJsMessage:" + msg);
//给JS发送一个消息
JSONObject object = new JSONObject();
object.put("cmd",1001);
object.put("msg","I'm Anroid");
AppActivity.postMessageToJs(object);
break;
}
}catch (JSONException e){
e.printStackTrace();
}
return "";
}
测试例子
从cocos中传递命令号1001,数据I'm JS给Android,Android收到后返回一个I'm Android给Cocos。
start(){
//派发事件给android
cc["MainScene"] = MainScene;
let obj:any = {};
obj.cmd = 1001;
obj.msg = "I'm JS";
MainScene.postMessageToAndroid(obj);
}
android studio输出信息
![](https://img-blog.csdnimg.cn/img_convert/16b0559a7a10d45bf6f3417e661237dc.png)
四 监听返回键
![](https://img-blog.csdnimg.cn/img_convert/211a4cef36ee4a10c524b53088b2caa2.png)
android中使用onKeyDown监听返回键,当用户点击返回键或使用手势返回时,派发事件2001给Cocos。
AppActivity.java:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//点击返回键 getRepeatCount()是重复次数,为防止点击过快或长按导致不停派发事件
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
try{
JSONObject object = new JSONObject();
object.put("cmd",2001);
AppActivity.postMessageToJs(object);
}catch (JSONException e){
}
return false;
}
return false; //false 继续传播事件 true停止传播事件
}
cocos监听到返回键事件2001,弹出一个确认框,用户点击取消则关闭弹框;用户点击确认则发送事件2002给android,告知android可以退出游戏。
MainScene.ts:
/**
* 接收来自安卓的原生消息
* @param data json格式字符串
*/
public static revAndroidMsg(data) {
let json = JSON.parse(data);
let cmd = json.cmd;
console.log("[MainScene] revAndroidMsg:",json.cmd);
switch (cmd) {
case 1001:
break;
case 2001: //点击返回键
App.Panel.open(AssetConst.ConfirmPanel, {
msg: "是否退出游戏?",
okCB: ()=>{ //确认回调
let data = {cmd:2002};
MainScene.postMessageToAndroid(data)
},
target: this, //回调执行对象
okStr: "退出", //确认按钮文本
});
break;
}
}
android收到2002事件,调用System.exit(0)关闭app应用。
AppActivity.java:
/**
* 接收来自JS的消息
* @param data json格式字符串
* @return 返回数据
*/
public static String revJsMessage(String data) {
Log.v("v","[Android] revJsMessage:" + data);
try{
JSONObject revObj = new JSONObject(data);
int cmd = revObj.getInt("cmd");
switch (cmd){
case 1001:
break;
case 2002: //退出
System.exit(0);
break;
}
}catch (JSONException e){
e.printStackTrace();
}
return "";
}
五 遇到问题
1 没有自动import
安卓没有自动import,提示找不到Cocos2dxJavascriptJavaBridge,也找不到app,所以我写的全路径,也可以自己手动import。
![](https://img-blog.csdnimg.cn/img_convert/7132ad7f14e81e3ef88638a8eb38cee1.png)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)