前言
cocos随笔系列将记录我平常用cocos creator遇到的一些散乱的知识点。今天讲讲cocos与android的交互与自动化
ts -> android
ts发起调用
在TestNativePlugin.ts的start里发起调用
jsb.reflection.callStaticMethod(
'com/bw/plugin/NativePlugin',
'sendMsgToPlugin',
'(Ljava/lang/String;)V',
'test');
参数的意思:
'com/bw/plugin/NativePlugin': 指的android导出项目的java目录下com/bw/plugin/NativePlugin.java里的NativePlugin类
'sendMsgToPlugin': 因为是callStaticMethod,所以是NativePlugin的静态方法
'(Ljava/lang/String;)V': 该方法的参数及返回值类型,即static void sendMsgToPlugin(String s)
'test': 传递给sendMsgToPlugin的实参
总结:
相当于调用com/bw/plugin/NativePlugin.java的 NativePlugin.sendMsgToPlugin('test')
android处理函数
在项目根目录下按照build路径添加NativePlugin.java:
cocos_learn\build-templates\
jsb-link\frameworks\runtime-src\proj.android-studio\src\
com\bw\plugin\NativePlugin.java
之所以要在build-templates目录下按build结构添加文件,是因为creator build的时候会把这个目录下的文件拷贝到构建目录去,这样我们就不用手动处理了。
然后编写NativePlugin.java测试:
package com.bw.plugin;
import android.util.Log;
import android.widget.Toast;
import org.cocos2dx.javascript.AppActivity;
import org.cocos2dx.lib.Cocos2dxHelper;
public class NativePlugin {
static final String TAG = "NativePlugin";
public static void sendMsgToPlugin(String s) {
Log.i(TAG, "sendMsgToPlugin:" + s);
if (s.equals("test")) {
// 当前是引擎GL线程,UI调用需要在UI线程
final String msg = s;
AppActivity app = (AppActivity)Cocos2dxHelper.getActivity();
app.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Cocos2dxHelper.getActivity(), msg, Toast.LENGTH_SHORT).show();
}
});
}
}
}
代码解读: 当收到的消息是'test'时,去UI线程显示toast提示。
实际应用中可将s按JSON解析,然后调用对应的模块去处理,或者直接转发消息出去,这里不再延伸。
我在TestNativePlugin.ts的start里发起调用,这样app一启动就会弹出toast提示。
android -> ts
android发起调用
android执行后,需要向ts返回结果。
继续上面的例子,在NativePlugin.java里添加:
public static void sendMsgToEngine(String s, boolean async) {
if (!async) {
Cocos2dxJavascriptJavaBridge.evalString("window.__native('" + s + "')");
} else {
final String msg = s;
Cocos2dxHelper.runOnGLThread(new Runnable() {
@Override
public void run() {
sendMsgToEngine(msg, false);
}
});
}
}
总结:
相当于调用ts:
window.__native(msg)
注意:上面区分了同步和异步,保险的话都走异步即可,只是有时候需要同步获得返回结果则需要同步。
注意调用该函数时所在的线程,如果是android ui调用则一定要异步。
然后在Toast.makeText后面添加调用:
sendMsgToEngine("test_ok;android", true);
ts处理函数
在TestNativePlugin.ts的onLoad设置处理函数:
onLoad () {
let w = window as any;
w.__native = (s:string)=>{
cc.log('native msg:', s);
let arr = s.split(';');
let type = arr[0];
if (type == 'test_ok') {
this.label.string = 'test ok:' + arr[1];
}
};
}
代码解读: 将收到的消息按分号拆分,参数1是'test_ok'时,label显示第2个参数。
这时运行app,屏幕中的label会显示
test ok: android
自动化
build-templates拷贝
在build-templates下按build路径存放文件,在build后会被自动拷贝过去。
插件替换
但如果接入sdk复杂后,需要修改引擎生成的文件,比如AppActivity.java。
如果也修改了然后放到build-templates下,可以解一时之需,如果引擎升级更改了AppActivity.java,则可能出问题。
我想到的方案是关键字替换,这个方案热更新插件也使用了。
具体思路:
1.编写插件,处理编辑器消息'before-change-files'
2.读取需要更改的文件(比如:AppActivity.java)
3.查找关键字替换,有则替换,无则提示错误(则需要检查该文件) 比如:
'SDKWrapper.getInstance().init(this);'
->
`SDKWrapper.getInstance().init(this);
api.create();`,
4.存储修改
完整代码先不放了,这个例子还用不上,后面有需求再细说吧。
后语
好了,今天就讲到这儿了,喜欢的朋友关注或转发一下,谢谢!
下期继续讲ios交互与自动化。
ps: 点击阅读原文可查看本文源码。