在HarmonyOS应用开发中,实现应用侧与前端页面(通常是Web组件)之间的交互是构建高质量应用的关键一环。本文将详细介绍如何利用HarmonyOS提供的API,特别是runJavaScript()
方法,来调用前端页面的JavaScript函数,并通过createWebMessagePorts()
接口建立两者之间的消息传递机制。让我们一步步深入,探索如何无缝集成应用逻辑与Web内容。
1. 理解基础概念
runJavaScript()
: 允许应用侧执行嵌入Web组件中的JavaScript代码,实现对前端页面功能的调用。- 消息端口 (
WebMessagePort
): 提供了一种机制,允许应用侧与Web页面双向交换数据,增强两者间的通信能力。
2. 实现步骤
2.1 调用前端页面的JavaScript函数
首先,让我们看一个简单的例子,演示如何在点击应用侧按钮时,触发前端页面中的htmlTest()
函数。
应用侧代码 (xxx.ets
):
import web_webview from '@ohos.web.webview';
@Entry
@Component
struct WebComponent {
webviewController: web_webview.WebviewController = new web_webview.WebviewController();
build() {
Column() {
Web({ src: $rawfile('index.html'), controller: this.webviewController})
Button('runJavaScript')
.onClick(() => {
this.webviewController.runJavaScript('htmlTest()');
})
}
}
}
前端页面代码 (index.html
):
<!DOCTYPE html>
<html>
<body>
<script>
function htmlTest() {
console.info('JavaScript Hello World! ');
}
</script>
</body>
</html>
2.2 双向通信:应用与前端页面的消息传递
为了实现更复杂的交互,我们需要使用消息端口来创建一个双向通信通道。
应用侧代码 (xxx.ets
):
// ...(之前的代码保持不变)
Button('postMessage')
.onClick(() => {
try {
this.ports = this.webviewController.createWebMessagePorts();
this.ports[1].onMessageEvent((result: any) => {
// 处理从前端接收到的消息
});
this.webviewController.postMessage('__init_port__', [this.ports[0]], '*');
} catch (error) {
console.error(error);
}
})
前端页面代码 (index.html
) 修改:
<!-- ...(之前的代码保持不变)-->
<script>
window.addEventListener('message', function(event) {
if (event.data === '__init_port__') {
h5Port = event.ports[0];
h5Port.onmessage = function(e) {
// 处理从应用侧接收到的消息
};
}
});
function PostMsgToEts(data) {
if (h5Port) {
h5Port.postMessage(data);
}
}
</script>
3. 注册应用侧代码到前端页面
除了直接调用JavaScript,还可以通过注册应用侧的对象到前端页面,使前端可以直接调用这些对象的方法。
使用javaScriptProxy()
应用侧代码 (xxx.ets
) 注册示例:
Web({ src: $rawfile('index.html'), controller: this.webviewController})
.javaScriptProxy({
object: this.testObj,
name: "testObjName",
methodList: ["test"],
controller: this.webviewController
})
使用registerJavaScriptProxy()
对于动态注册,可以使用registerJavaScriptProxy()
接口,并在调用后刷新Web组件以确保注册生效。
应用侧代码 (xxx.ets
) 动态注册示例:
Button('Register JavaScript To Window')
.onClick(() => {
try {
this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
this.webviewController.refresh();
} catch (error) {
console.error(error);
}
})