下面给出「Web JavaScript ↔ ArkTS」双向通信的最小可运行例子, 全部代码复制到 DevEco Studio 即可直接跑通(API 11+,ArkTS Stage 模型)。 思路:用 Web 组件的 javaScriptProxy 把 ArkTS 对象注入到 H5 的 window 下, H5 调用注入方法即可把数据推到 ArkTS;反过来 ArkTS 用 runJavaScript 即可把数据推回 H5。
1. 目录结构
ts
entry/src/main/ets/pages/Index.ets
entry/src/main/resources/rawfile/index.html // 放 H5
2. ArkTS 侧(Index.ets)
typescript
import web_webview from '@ohos.web.webview';
interface JsBridge {
sendToArkTS(msg: string): string;
}
class JsBridgeImpl implements JsBridge {
sendToArkTS(msg: string): string {
console.info('Web说:' + msg);
return 'ArkTS 已收到:' + msg;
}
}
@Entry
@Component
struct WebJSArkTSConn {
private webCtrl = new web_webview.WebviewController();
private jsBridge: JsBridge = new JsBridgeImpl();
build() {
Column() {
Button('ArkTS → Web')
.onClick(() => {
// 2. ArkTS 主动调 H5 函数
this.webCtrl.runJavaScript(`receiveFromArkTS('Hello, I am ArkTS!')`);
})
Web({ src: $rawfile('index_2.html'), controller: this.webCtrl })
.javaScriptAccess(true)
.javaScriptProxy({
object: this.jsBridge,
name: 'ArkTSBridge', // 注入到 window 的变量名
methodList: ['sendToArkTS'],
controller: this.webCtrl
})
.width('100%')
.height('100%')
}
}
}
3. Web 侧(index.html)
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS ↔ ArkTS</title>
</head>
<body>
<button onclick="sendToArkTS()">Web → ArkTS</button>
<div id="result">等待 ArkTS 返回...</div>
<script>
// 被 ArkTS 调用的函数
function receiveFromArkTS(msg) {
document.getElementById('result').innerText = '收到 ArkTS:' + msg;
}
// 调用注入的对象
function sendToArkTS() {
if (window.ArkTSBridge && window.ArkTSBridge.sendToArkTS) {
const ret = window.ArkTSBridge.sendToArkTS('Hello, I am Web!');
document.getElementById('result').innerText = 'ArkTS 返回:' + ret;
} else {
alert('ArkTSBridge 未就绪');
}
}
</script>
</body>
</html>
4. 运行效果
- 点 「Web → ArkTS」 → H5 把字符串传给 ArkTS,立即拿到回执并显示。
- 点 「ArkTS → Web」 → ArkTS 主动把字符串推给 H5,页面实时刷新。
5. 注意事项
javaScriptProxy的methodList必须显式列出,否则方法不可见。- 如果后续需要双向异步事件,可再包一层
postMessage/onMessageEvent做事件总线 。 - 调试阶段在
onPageEnd回调里runJavaScript可确保 H5 已加载完成再调函数。
至此,最小双向通信完成,可在此基础上扩展任意复杂逻辑。祝开发顺利!
异常情况
ts
private jsBridge = {
// H5 调用的函数
sendToArkTS: (msg: string): string => {
console.info('Web说:' + msg);
// 可在这里把数据回显到 UI 或发回 H5
return 'ArkTS 已收到:' + msg;
}
};
语法有Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals) <ArkTSCheck
ts
private jsBridge : JsBridge = {
// H5 调用的函数
sendToArkTS: (msg: string): string => {
console.info('Web说:' + msg);
// 可在这里把数据回显到 UI 或发回 H5
return 'ArkTS 已收到:' + msg;
}
}as JsBridge;
一样有语法问题 arkts-no-untyped-obj-literals
鸿蒙开发有比较严格的语法检查,不同于 js 和 ts 的随意写法,一般都是 interface 和 class 以及 new 这三者组合完成对象实例化