Cocos版本:2.4.4
參考:
一 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。