标签: HarmonyOS

  • HarmonyOS中,html 与 ets 桥接沟通

    当前HarmonyOS中,添加Webview只有一种: Web

    流程解释

    需要先初始化webview.WebMessagePort,然后一个ets使用,发送一个端口给html去用。

    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>