cocos webview与通信
当前需求是在原有的cocos手机游戏里嵌入另一个cocos的web-mobile项目
所以需要使用webview
记录一下
首先就是要有一个webview组件
接下来是脚本
(外部项目)
export class GameWebview extends Component {
@property(WebView)
webview: WebView = null!;
onAdded(params: any) {
// webview跳转 并向内部发送token
let token = params.access_token;
this.webview.url = `${params.host}?token=${token}`;
// webview加载完成监听
this.webview.node.on(WebView.EventType.LOADED, ()=> {
// 约定的关键字
let scheme = "closepage";
// 设置关键字
this.webview.setJavascriptInterfaceScheme(scheme);
// 识别到URL前缀为关键字的回调
this.webview.setOnJSCallback(()=>{
this.close();
})
// 关闭背景音乐
oops.audio.stopMusic();
// 原本是想用这种方式发送token的,但是没有获取的时机
// this.scheduleOnce(()=> {
// this.webview.evaluateJS(`setToken(${JSON.stringify(token)})`);
// }, 8)
})
}
close() {
// 打开背景音乐
let bgm = oops.storage.get("game_audio");
oops.audio.playMusicLoop(bgm);
oops.gui.remove(UIID.HitMoleGameWebview);
}
}
(内部项目)
在Main.ts即项目开始时获取token
const token = urlParams.get("token");
oops.storage.set("token", token);
返回到外部游戏
close() {
SocketManager.getInstance().close();
// 跳转以关键字为前缀的URL,让外部webview识别
document.location = 'closepage://a=1';
oops.gui.remove(UIID.Home);
}
一些遇到的问题及解决
传递token
一开始我是想通过👇这种方式转递token
记得要stringify一下
this.webview.evaluateJS(`setToken(${JSON.stringify(token)})`);
获取的话就要通过声明全局方法setToken来接收
但找不到合适的时机
我已经在首场景下挂载的脚本(Main.ts)里声明了,但是还是接收不到,会报错找不到该方法(难道要改构建后的文件?)
然后我又尝试了在加载完成监听里发送token,还是同样不行
this.webview.node.on(WebView.EventType.LOADED, ()=> {
this.webview.evaluateJS(`setToken(${JSON.stringify(token)})`);
})
再然后又加了个延时,倒是可以了,但是不是很稳定
this.webview.node.on(WebView.EventType.LOADED, ()=> {
this.scheduleOnce(()=> {
this.webview.evaluateJS(`setToken(${JSON.stringify(token)})`);
}, 8)
})
最后就直接用url来传了
this.webview.url = `${params.host}?token=${token}`;
接收
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get("token");
内部向外部传递消息
一开始我是这么设置关键字的
let scheme = "closepage";
this.webview.setJavascriptInterfaceScheme(scheme);
this.webview.setOnJSCallback(()=>{
this.close();
})
let token = params.access_token;
this.webview.url = `${params.host}?token=${token}`;
看了半天,并没有啥问题啊,就是识别不了关键字
看了这篇帖子
应该是要先打开webview的内部项目,激活,再去设置关键字,为了保险我是在loaded里设置的关键字
this.webview.node.on(WebView.EventType.LOADED, ()=> {
// 约定的关键字
let scheme = "closepage";
// 设置关键字
this.webview.setJavascriptInterfaceScheme(scheme);
// 识别到URL前缀为关键字的回调
this.webview.setOnJSCallback(()=>{
this.close();
})
})
还有注意关键字不能有大写字母!!
web-mobile打包问题
打包时要注意,记得勾选上MD5,这样重新上传新包后就不用清缓存才能加载新包内容了
细节问题
- 记得跳转时要记得关闭原bgm,返回时重新播放bgm
- 如果内部项目是用的浏览器预览,可以选择”网页全屏“