流程解释
需要先初始化webview.WebMessagePort,然后一个ets使用,发送一个端口给html去用。
来个视频展示一下效果(文件有点大,1.8M,估计要载入一会儿):
这里的流程蛮有意思的,画个图解释一下。
ets端
// ... const HARMONY_PORT = 0; const HTML_PORT = 1; // ... export default struct AppWebViewPage { // ... build() { Web({ src: this.url, controller: this.webviewController, }) .onPageEnd(() => { try { this.ports = this.webviewController.createWebMessagePorts() || []; // 这里会返回2个端口。 // 有点类似于 实例化了一个网页和鸿蒙之间发送消息的管道,然后把管道的两个头作为端口返回回来 // 所以这里就有有2个端口,也就是这个通信管道的2个头 // 那么 // 1. 使用 HARMONY_PORT 端口,作为鸿蒙的端口,用来发送和接收消息 // 2. 使用 HTML_PORT 端口,作为html的端口,把这个端口通过 HARMONY_PORT 端口发给html,让html来使用。 if (!this.ports || this.ports.length < 2) { hilog.error(1, 'Error', '创建端口失败:返回端口数量不足'); return; } /* 端口0, 给鸿蒙端使用 */ this.ports[HARMONY_PORT].onMessageEvent((result: webview.WebMessage) => { this.onMessageEvent(result); }); /* 端口1, 发送给html进行使用 */ this.webviewController.postMessage('__init__project__', [this.ports[HTML_PORT]], '*'); } catch (e) { hilog.error(1, 'Error', '初始化 WebMessagePort 失败:' + JSON.stringify(e)); } }) } /** * 接收到H5消息 * @param result */ private onMessageEvent(result: webview.WebMessage) { let msg = ''; try { msg = result.toString() || ''; hilog.info(1, 'INFO', 'onMessageEvent:' + msg); } catch (e) { hilog.error(1, 'Error', '获取消息字符串失败:' + JSON.stringify(e)); return; } } /** * 向H5发布消息 * @param message */ public sendMessageToH5(message: string) { hilog.info(1, 'INFO', 'sendMessageToH5:' + message); try { this.ports[HARMONY_PORT].postMessageEvent(message); } catch (error) { hilog.error(1, 'Error', '向H5发布消息失败:' + JSON.stringify(error)); } } }html 端
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Harmony H5 Demo</title> </head> <body> <h1>H5 Page</h1> <button onclick="sendMsgToEts()">发送消息到鸿蒙侧</button> <h2>日志记录</h2> <pre id="logHistory"></pre> <script> let messagePort = null; function appendLog(message) { const logHistory = document.getElementById("logHistory"); const logLine = new Date().toLocaleTimeString() + " - " + message; logHistory.textContent = logHistory.textContent ? logLine + "\n" + logHistory.textContent : logLine; } appendLog("页面已初始化,等待鸿蒙侧端口..."); window.addEventListener("message", function (event) { if (event.data === "__init__project__" && event.ports && event.ports.length > 0) { messagePort = event.ports[0]; if (typeof messagePort.start === "function") { messagePort.start(); } console.log("H5 Port initialized"); appendLog("端口初始化成功"); messagePort.onmessage = function (portEvent) { appendLog("收到鸿蒙侧消息: " + portEvent.data); }; } }); function sendMsgToEts() { if (messagePort) { const obj = { name: "我是html的来的消息,发给鸿蒙的", value: 123 }; messagePort.postMessage(JSON.stringify(obj)); } else { console.error("messagePort is null, Please initialize first"); appendLog("发送失败: messagePort is null, Please initialize first"); } } </script> </body> </html>