【原生】CocosCreator Android和游戏的通讯 (Java和TS互相调用、传递JSON数据、监听返回键)

2023-05-16

Cocos文档-Java原生反射机制

如何在 Android 平台上使用 JavaScript 直接调用 Java 方法 · Cocos Creator

Cocos文档-JSB使用指南

JSB 2.0 使用指南 · Cocos Creatorhttps://docs.cocos.com/creator/manual/zh/advanced-topics/JSB2.0-learning.html

一  Cocos中调用Android方法

二 Android中调用Cocos方法

三 传递JSON数据

四 监听返回键 

五 遇到的问题

cocos和android的互相调用,在Java中可以调用TypeScript的方法,在TypeScript中可以调用Java的方法。

一 Cocos中调用Android方法: jsb.reflection.callStaticMethod

通过反射机制直接在 JavaScript 中调用 Java 的静态方法。

反射机制:Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

在android的AppActivity中定义一个方法

在cocos中调用Android定义的方法,传递参数hello。


    start(){
        let result = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "AndroidFun", "(Ljava/lang/String;)Ljava/lang/String;", "hello");
    }
  

  

运行android项目,可以看到调用成功

 

二 Android中调用Cocos的方法:Cocos2dxJavascriptJavaBridge.evalString

 在Cocos的MainScene.ts中定义方法

MainScene.ts需要赋值给cc,不然android访问不到这个方法,这段代码必须放在android调用cocos方法之前,可以游戏初始化时执行这段代码。

目前引擎并未承诺多线程下的安全性,所以在开发过程中需要避免 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的方法,并输出了调试信息

 三 传递JSON数据

 原生和cocos的互相传递json消息,因为json可以自定义各种数据,比较方便。

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输出信息   

四 监听返回键

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。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【原生】CocosCreator Android和游戏的通讯 (Java和TS互相调用、传递JSON数据、监听返回键) 的相关文章

  • 茶叶品种

    茶叶 文章目录 茶叶花茶碧潭飘香 360雪花针螺 370 铁观音祥明清香4A观音 490 正式工作之余 学习点其他行业的信息 充实自己 花茶 碧潭飘香 360 雪花针螺 370 铁观音 祥明清香4A观音 490
  • 微信小程序如何关闭云开发

    需求 新建项目一不小心就会把云开发打开 xff0c 给开发者带来一些麻烦 接下来 xff0c 小编结合自己的开发经验 xff0c 给大家说说如何关闭微信小程序开发工具中的云开发功能 原文 微信小程序如何关闭云开发 解决步骤 首先打开云开发控
  • 如何删除Word文档中的空白页

    需求 平常我们写 Office 文档的时候 xff0c 经常会不小心多加几页空白 xff0c 那么如何删除 word 文档中的空白页呢 xff1f 小编结合网友提供的办法和亲身测试的操作经验 xff0c 给大家提供几个可行的方案 原文 xf
  • 使用 x-sheet 构建在线疫情高峰预测数据表

    背景 最近 xff0c 一位大数据专家通过百度 发烧 的搜索指数 公开的疫情感染人数等指标 xff0c 计算出每个城市的 超额发烧搜索指数累计面积 xff0c 并且通过城市的搜索指数累计增长 累计速度 xff0c 就可以算出现在每一个有疫情
  • Python初学者笔记:打印出斐波那契数列的前10项

    问题 xff1a 斐波那契数列 xff08 意大利语 Successione di Fibonacci xff0c 又称黄金分割数列 费波那西数列 费波拿契数 费氏数列 xff0c 指的是这样一个数列 xff1a 0 1 1 2 3 5 8
  • Python初学者笔记(3):输出列表中的奇数/奇数项,字符串中的偶数项,字符串大小写转换

    1 a 61 8 13 11 6 26 19 24 1 xff09 请输出列表a中的奇数项 2 xff09 请输出列表a中的奇数 解 xff1a 1 xff09 1 a 61 8 13 11 6 26 19 24 2 print a 2 R
  • 从txt中读入数据到数组中(fscanf)

    C sources include lt stdio h gt int main FILE fp 定义一个文件 fp 61 fopen 34 p5 txt 34 34 r 34 if fp 61 61 NULL printf 34 ERRO
  • iOS开发——高德地图调研(路线规划,周边搜索,)

    只需要经纬度即可完成 xff01 xff08 初学 求大神指点 xff01 xff09 import 34 BaseViewController h 34 64 interface MapViewController BaseViewCon
  • Hexo Next 博客添加相册瀑布流

    原文 xff1a https rebootcat com 2020 09 19 nextphotowall 前言 一直没有时间来整理下博客搭建的一些事情 xff0c 现在补上一篇 xff0c 给 Hexo Next 博客添加一个相册功能 x
  • Epoll原理深入分析

    原文 xff1a https rebootcat com 2020 09 26 epoll cookbook Epoll 的出现 想必能搜到这篇文章的 xff0c 应该对 select poll 有一些了解和认识 xff0c 一般说 epo
  • 模仿nginx修改进程名

    个人博客原文 xff1a https rebootcat com 2020 10 25 setproctitle nginx 进程名 使用 nginx 的过程中 xff0c 我们经常看到 nginx 的进程名是不同的 xff0c 如下 xf
  • MAC终端下使用IDEA自带的Git拉取github项目,提示SSL_ERROR_SYSCALL in connection to XX

    MAC终端下使用IDEA自带的Git拉取github项目 xff0c 提示SSL ERROR SYSCALL in connection to XX 出处 xff1a https www cnblogs com life of coding
  • TCP全连接和半连接的问题探讨

    个人博客 xff1a https rebootcat com 2020 11 14 tcp accept 从何说起 说起 tcp 的连接过程 xff0c 想必 3次握手4次挥手 是大家广为熟知的知识 xff0c 那么关于更细节更底层的连接过
  • 深入浅出paxos

    原文 https rebootcat com 2020 12 05 paxos
  • P2P打洞技术详解

    原文 xff1a https rebootcat com 2021 03 28 p2p nat traversal 何为打洞 xff1f what 英文翻译 NAT traversal NAT 穿越NAT Hole Punching NAT
  • Windows SDK 7.1 (包含directshow)安装配置

    最近一直在做毕业设计的事情 xff0c 需要利用directshow进行视频开发 xff0c 但是现在单独的directshow包已经没有了 xff0c 从directx9 0c开始directshow和directx分开发布 xff0c
  • 右键弹出菜单和快捷键的设置

    写MFC xff0c 少不了用到菜单和快捷键 xff0c 此处我用到了右键菜单 我的项目是一个播放器的实现 xff0c 那么在屏幕中央右键点击 xff0c 应该会弹出右键菜单 xff0c 比如播放 xff0c 暂停等 xff0c 如我这样
  • Combox控件下拉选择不同值触发的动作响应

    项目中需要根据combox控件下拉列表选择不同的值 xff0c 然后能触发相应的动作 比如我的项目中 xff0c 通过combox空间的下拉列表选择不同的C盘 xff0c D盘 xff0c E盘 xff0c F盘 xff0c 然后能在lis
  • 64位win7安装vs2010出现“组件安装失败...”等问题的解决方法

    如题 xff0c 公司发了新电脑 xff0c 安装的是64位win7 我原来的本本安装的是32位的win7 xff0c 当时安装vs2010的时候并没有那么多事 xff0c 这次安装却真是让我蛋疼至极 先后下了3个vs的安装包 xff0c
  • 如何清除alibaba pcsafe service

    管理员打开cmd xff1b 执行sc delete AlibabaProtect xff1b 然后重启 xff0c 找到c program files alibaba 把该文件夹全删光 更新 xff1a 后来发现这样操作后 xff0c 没

随机推荐