【原生】CocosCreator Android和游戲的通訊 (Java和TS互相調用、傳遞JSON數據、監聽返回鍵)


Cocos版本:2.4.4

參考:

Cocos文檔-Java原生反射機制

Cocos文檔-JSB使用指南

 

一  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。

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM