鸿蒙Next中H5页面与原生应用如何相互调用

在鸿蒙Next系统中,H5页面和原生应用之间具体如何实现相互调用?能否提供具体的API调用示例或代码片段?比如H5页面如何触发原生功能,原生应用又如何回调H5页面的方法?另外,这种交互方式是否存在性能或安全性方面的限制?

2 回复

鸿蒙Next里,H5和原生应用互相调用的方式就像两个邻居串门:

  • H5喊原生:用WebViewpostMessage发消息,原生用onMessage接活儿。
  • 原生叫H5:直接WebView执行JavaScript代码,比如webView.executeJs("alert('嗨!')")
    简单说,一个靠“传纸条”,一个靠“喊话”,配合默契!

更多关于鸿蒙Next中H5页面与原生应用如何相互调用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在鸿蒙Next中,H5页面与原生应用通过ArkWeb组件和WebMessagePort机制实现双向通信。以下是具体方法:


1. H5调用原生方法

步骤:

  1. 原生侧注册JavaScript接口
    ArkWeb中通过registerJavaScriptProxy()注入对象:

    // 原生代码(eTS/ArkTS)
    import web_webview from '[@ohos](/user/ohos).web.webview';
    
    [@Entry](/user/Entry)
    [@Component](/user/Component)
    struct WebComponent {
      controller: web_webview.WebviewController = new web_webview.WebviewController();
    
      build() {
        Column() {
          // 注册名为"nativeBridge"的JS对象,供H5调用
          ArkWeb({ 
            src: $rawfile("index.html"),
            controller: this.controller
          })
          .javaScriptAccess(true)
          .onPageEnd(() => {
            // 注入原生对象到H5全局环境
            this.controller.registerJavaScriptProxy({
              objectName: "nativeBridge",
              methodList: ["showToast", "getDeviceInfo"]
            });
          })
        }
      }
    
      // 供H5调用的方法
      showToast(message: string) {
        // 显示原生Toast
        prompt.showToast({ message: `H5传递参数: ${message}` });
      }
    
      getDeviceInfo() {
        return { os: "HarmonyOS", version: "4.0" };
      }
    }
    
  2. H5侧调用原生方法

    <!-- H5页面 -->
    <button onclick="callNative()">调用原生Toast</button>
    <script>
      function callNative() {
        if (window.nativeBridge) {
          // 调用原生方法(无返回值)
          nativeBridge.showToast("Hello from H5!");
          // 调用原生方法(有返回值)
          const info = nativeBridge.getDeviceInfo();
          console.log("设备信息:", info);
        }
      }
    </script>
    

2. 原生调用H5方法

步骤:

  1. H5侧注册方法供原生调用

    <script>
      // 定义全局函数供原生调用
      function onNativeCall(data) {
        document.getElementById("msg").innerText = "原生传递数据: " + data;
      }
    </script>
    
  2. 原生侧调用H5方法
    使用runJavaScript()执行JS代码:

    // 原生代码
    [@Component](/user/Component)
    struct WebComponent {
      controller: web_webview.WebviewController = new web_webview.WebviewController();
    
      callH5Method() {
        // 调用H5的全局函数并传递参数
        this.controller.runJavaScript({
          script: `onNativeCall("${JSON.stringify({ type: 'event', value: 123 })}")`
        });
      }
    }
    

3. 双向通信(推荐)

使用WebMessagePort建立持久通道:

  1. 原生侧创建端口

    // 创建消息端口
    const msgPort = this.controller.createWebMessagePort();
    // 绑定到H5的window对象
    this.controller.postWebMessage({
      message: { type: "initPort", port: msgPort },
      uri: "*"
    }, [msgPort]);
    
    // 监听H5发送的消息
    msgPort.onMessageEvent((result: web_webview.WebMessage) => {
      console.log("收到H5消息:", result.data);
    });
    
  2. H5侧接收端口并通信

    <script>
      window.addEventListener('message', (event) => {
        if (event.data.type === 'initPort') {
          const h5Port = event.ports[0];
          // 向原生发送消息
          h5Port.postMessage("H5就绪");
          
          // 监听原生消息
          h5Port.onmessage = (e) => {
            console.log("收到原生消息:", e.data);
          };
        }
      });
    </script>
    

注意事项:

  1. 需在module.json5中声明ohos.permission.INTERNET权限(如果需要加载网络页面)。
  2. 使用registerJavaScriptProxy注册的方法必须通过@Expose注解标记(如需跨线程调用)。
  3. 通过ArkWebonConsole事件可捕获H5的console.log输出。

通过以上方法,可实现H5与原生应用的高效双向通信,兼顾灵活性和性能。

回到顶部