鸿蒙 HarmonyOS Next 开发中 ArkWeb 与原生交互方式及注意事项

一、ArkWeb 与原生交互方式

(一)原生向 Web 注入 JavaScript 代码

1. 原理

在原生应用中,通过 ArkWeb 提供的 API 向 Web 页面注入 JavaScript 代码,从而实现对 Web 页面的控制和数据传递。

2. 代码示例

import { Web, WebRef, WebPageLoadEvent } from '@ohos.web.webview';

@Entry

@Component

struct NativeToWebExample {

  private webRef: WebRef | null = null;

  build() {

    Column({ space: 50 }) {

      Web({

        src: 'https://example.com',

        onPageLoadFinish: (event: WebPageLoadEvent) => {

          if (this.webRef) {

            // 注入JavaScript代码

            this.webRef.executeJs('document.getElementById("demo").innerHTML = "Hello from Native";');

          }

        }

      })

      .width('100%')

      .height('80%')

      .ref((ref) => {

        this.webRef = ref;

      })

      Button('Send Message to Web')

        .onClick(() => {

          if (this.webRef) {

            this.webRef.executeJs('alert("Message from native app!");');

          }

        })

    }

  }

}

(二)Web 向原生发送消息

1. 原理

在 Web 页面中,使用window.postMessage方法向原生应用发送消息,原生应用通过监听onMessageReceived事件接收消息。

2. 代码示例

Web 页面代码(HTML + JavaScript)

<!DOCTYPE html>

<html>

<head>

  <meta charset="UTF-8">

  <title>Web to Native</title>

</head>

<body>

  <button onclick="sendMessageToNative()">Send Message to Native</button>

  <script>

    function sendMessageToNative() {

      window.postMessage('Hello from Web', '*');

    }

  </script>

</body>

</html>

原生应用代码(ArkTS)

import { Web, WebMessageEvent } from '@ohos.web.webview';

@Entry

@Component

struct WebToNativeExample {

  build() {

    Web({

      src: 'file:///data/storage/el2/base/haps/entry/files/webpage.html',

      onMessageReceived: (event: WebMessageEvent) => {

        console.log('Received message from web: ' + event.data);

      }

    })

    .width('100%')

    .height('100%')

  }

}

(三)原生与 Web 双向数据绑定

1. 原理

结合上述两种方式,实现原生与 Web 之间的数据双向同步,当原生数据变化时更新 Web 页面,当 Web 页面数据变化时更新原生数据。

2. 代码示例

import { Web, WebRef, WebPageLoadEvent, WebMessageEvent } from '@ohos.web.webview';

@Entry

@Component

struct BiDirectionalBindingExample {

  private webRef: WebRef | null = null;

  private nativeData: string = 'Initial Value';

  build() {

    Column({ space: 50 }) {

      Web({

        src: 'https://example.com',

        onPageLoadFinish: (event: WebPageLoadEvent) => {

          if (this.webRef) {

            // 初始化Web页面数据

            this.webRef.executeJs(`document.getElementById("data-display").innerHTML = "${this.nativeData}";`);

          }

        },

        onMessageReceived: (event: WebMessageEvent) => {

          // 更新原生数据

          this.nativeData = event.data;

          console.log('Updated native data: ' + this.nativeData);

        }

      })

      .width('100%')

      .height('80%')

      .ref((ref) => {

        this.webRef = ref;

      })

      Button('Update Web Data')

        .onClick(() => {

          this.nativeData = 'New Value';

          if (this.webRef) {

            // 更新Web页面数据

            this.webRef.executeJs(`document.getElementById("data-display").innerHTML = "${this.nativeData}";`);

          }

        })

    }

  }

}

二、注意事项

(一)安全性方面

1、输入验证

原生向 Web 注入 JavaScript 代码时,要对注入的代码进行严格的输入验证,防止恶意代码注入。例如,避免直接将用户输入作为 JavaScript 代码注入,应进行转义和过滤。

Web 向原生发送消息时,原生应用要对接收的消息进行合法性检查,防止接收恶意消息。

2、跨域安全

在使用window.postMessage时,要明确指定目标源(targetOrigin),避免消息被恶意拦截或篡改。例如,在 Web 页面中使用window.postMessage('message', 'https://example.com'),确保消息只能发送到指定的源。

(二)性能方面

1、减少频繁交互

频繁的原生与 Web 交互会影响应用的性能,尽量减少不必要的交互。例如,避免在短时间内多次向 Web 注入大量 JavaScript 代码或频繁发送消息。

2、异步处理

对于耗时的交互操作,如网络请求、大量数据处理等,要采用异步处理方式,避免阻塞主线程。例如,在原生应用中使用Promise或async/await处理耗时操作。

(三)兼容性方面

1、浏览器内核差异

HarmonyOS 中的 ArkWeb 可能采用不同的浏览器内核,要确保 Web 页面在各种内核下都能正常与原生应用交互。可以进行多内核测试,针对不同内核进行必要的兼容性处理。

2、版本兼容性

要注意 ArkWeb API 的版本兼容性,不同版本的 HarmonyOS 可能支持不同的 API。在开发过程中,要根据目标设备的系统版本选择合适的 API 进行开发。

(四)内存管理方面

1、及时释放资源

在 Web 页面不再使用时,要及时释放相关资源,避免内存泄漏。例如,在组件销毁时调用Web组件的清理方法。

@Component

struct MemoryManagementExample {

  private webRef: WebRef | null = null;

  aboutToDisappear() {

    if (this.webRef) {

      this.webRef.destroy();

    }

  }

  build() {

    Web({

      src: 'https://example.com'

    })

    .width('100%')

    .height('100%')

    .ref((ref) => {

      this.webRef = ref;

    })

  }

}

2、数据缓存管理

对于交互过程中产生的数据缓存,要进行合理的管理,避免占用过多内存。例如,定期清理不再使用的缓存数据。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容