前言:cocos creator3.x 变化还是比较大的,很多 api 都变了。这里给大家填个坑;
我这里使用的是 3.5.2 版本
TS 调用 java:
官方文档:如何在 Android 平台上使用 JavaScript 直接调用 Java 方法 · Cocos Creator
creator 中的 TS脚本:
if (sys.os == sys.OS.ANDROID) { let className = "com/cocos/game/AppActivity"; let methodName = "showAd_unified"; let methodSignature = "()V"; jsb.reflection.callStaticMethod(className, methodName, methodSignature); } else if (sys.os == sys.OS.IOS) { }
- className: 原生工程中 类文件名路径,对应脚本名称
- methodName: .java 文件中对应的 静态方法名称
private static void showAd_unified(){ activity.runOnUiThread(new Runnable() { @Override public void run() { showInsertAd(); } }); }- methodSignature: 静态方法参数类型,也叫 方法签名
方法签名稍微有一点复杂,最简单的方法签名是
()V
,它表示一个没有参数没有返回值的方法。其他一些例子:
(I)V
表示参数为一个 int,没有返回值的方法(I)I
表示参数为一个 int,返回值为int的方法(IF)Z
表示参数为一个 int 和一个 float,返回值为 boolean 的方法
括号内的符号表示参数类型,括号后面的符号表示返回值类型。因为 Java 是允许函数重载的,可以有多个方法名相同但是参数返回值不同的方法,方法签名正是用来帮助区分这些相同名字的方法的。
目前 Cocos Creator 中支持的 Java 类型签名有以下 4 种:
Java 类型 签名 int I float F boolean Z String Ljava/lang/String; 参数可以是 0 个或任意多个,直接使用 JavaScript 中的 number、bool 和 string 就可以。
使用示例:
// 调用 hello 方法 jsb.reflection.callStaticMethod("com/cocos/game/Test", "hello", "(Ljava/lang/String;)V", "this is a message from JavaScript"); // 调用第一个 sum 方法 var result = jsb.reflection.callStaticMethod("com/cocos/game/Test", "sum", "(II)I", 3, 7); log(result); // 10 // 调用第二个 sum 方法 var result = jsb.reflection.callStaticMethod("com/cocos/game/Test", "sum", "(I)I", 3); log(result); // 5
小结:有两点需要 注意下:
- TS 只能调用 Java 静态方法:
- 应为 Cocos Creator 是在 GL 线程中的,所有在执行Java 方法的时候 要切换到 UI线程
private static void showAd_unified(){ // activity = this; // activity 是当前的 activtiy activity.runOnUiThread(new Runnable() { @Override public void run() { /// TODO } }); }
Java 调用 TS:
这里变化还是比较大的
之前的方法是这个:(后来发现 runOnGLThread怎么点都不出来 )
activty.runOnGLThread(new Runnable() { @Override public void run() { //相当于直接在项目运行后的console里执行代码 eval() 字符串形式 Cocos2dxJavascriptJavaBridge.evalString("cc.log(\"Javascript Java bridge!\")"); } });3.X 已经长这样:
CocosHelper.runOnGameThread(new Runnable() { @Override public void run() { CocosJavascriptJavaBridge.evalString(String.format("cc.find('Canvas/Layout').getComponent('NativeMannager').showAnimation(%s);", value)); } });后面参数写法和 unity 的还是很像的,先找到 对应的 Node 节点取上面的脚本再调用方法
传参的时候 当参数特别长 或者 json字符串 或者 参数中有特殊字符串 的时候,需要转一下Base64
static void callJSFunction(final String value){ String strBase64 = Base64.encodeToString(value.getBytes(), Base64.DEFAULT); final String jsCall = String.format("cc.find('Canvas/Layout').getComponent('NativeMannager').showAnimation('%s');", strBase64); Log.d("AdvertisingManager",jsCall); CocosHelper.runOnGameThread(new Runnable() { @Override public void run() { CocosJavascriptJavaBridge.evalString(jsCall); //JsbBridge.sendToScript(); } }); }
(手头没有 mac 后期补充上)