一、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、数据缓存管理
对于交互过程中产生的数据缓存,要进行合理的管理,避免占用过多内存。例如,定期清理不再使用的缓存数据。