HarmonyOS中,html 与 ets 桥接沟通
当前HarmonyOS中,添加Webview只有一种: Web
流程解释
需要先初始化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>
一只孤独的猫咪神!喵!
浙公网安备 33010602011771号