当前位置:首页>鸿蒙APP>鸿蒙ArkTS与H5双向通信实战:从原理到可运行案例

鸿蒙ArkTS与H5双向通信实战:从原理到可运行案例

  • 2026-11-10 06:17:40
鸿蒙ArkTS与H5双向通信实战:从原理到可运行案例

鸿蒙ArkTS与H5双向通信实战:从原理到可运行案例,一文吃透

在鸿蒙HarmonyOS原生开发中,ArkTS作为主力开发语言,经常需要与H5页面进行交互——比如原生应用内嵌H5网页、H5调用鸿蒙系统能力(如获取设备信息、弹窗提示)、ArkTS向H5传递数据(如用户信息、配置参数)。

很多开发者在做混合开发时,会遇到“通信失败”“参数传不过去”“回调无响应”等问题,核心原因是没掌握鸿蒙官方推荐的通信方式,以及两端交互的细节规范。

本文将从「通信原理」入手,拆解ArkTS与H5双向通信的两种核心方式,提供可直接复制、跑通无压力的完整案例(含ArkTS代码+HTML代码),兼顾新手友好性和实战性,看完就能落地。

一、先搞懂:ArkTS与H5通信的核心原理

ArkTS与H5通信,本质是通过「Web组件」作为桥梁,实现两个环境的数据流转。鸿蒙官方提供了两种主流通信方式,覆盖不同开发场景:

  1. JS注入(registerJavaScriptProxy):ArkTS向H5注入一个全局JS对象,H5直接调用该对象的方法,实现「H5→ArkTS」的通信(最常用、最简洁);

  2. 脚本执行(runJavaScript):ArkTS主动执行H5页面中的JS函数,实现「ArkTS→H5」的通信;

补充:鸿蒙Web组件支持通过MessagePorts实现更灵活的双向异步通信,但对于大部分业务场景,上述两种方式已足够覆盖,且上手更简单。本文重点讲解最常用的「JS注入+脚本执行」组合,兼顾实用性和易操作性。

核心前提:H5页面必须通过Web组件加载(本地H5/在线H5均可),且只有trustedurl中链接或src链接的网页,才能和ArkTS框架进行双向通信。

二、实战准备:环境与目录结构

1. 环境要求

  • DevEco Studio:4.1及以上

  • HarmonyOS SDK:API 10(NEXT)

  • 运行设备:模拟器(API 10)或鸿蒙真机

2. 目录结构(关键)

我们采用「本地H5」的方式(无需联网,更易测试),目录结构如下(重点关注rawfile文件夹):

entry├─ src/main│  ├─ ets                # ArkTS代码目录│  │  └─ pages│  │     └─ Index.ets    # 主页面(含Web组件)│  └─ resources          # 资源目录│     └─ rawfile          # 存放本地H5文件(必须叫这个名字)│        ├─ index.html   # H5页面│        └─ js│           └─ index.js  # H5交互逻辑└─ build.gradle          # 项目配置(无需修改)

注意:rawfile是鸿蒙规定的本地静态资源目录,用于存放HTML、JS、CSS等文件,Web组件可直接通过$rawfile('xxx.html')访问,无需配置额外路径。

三、完整可运行案例:双向通信实战

本次案例实现3个核心功能(覆盖日常开发80%场景):

  • ArkTS → H5:传递用户信息(对象类型),H5接收后展示;

  • H5 → ArkTS:调用鸿蒙系统弹窗(showToast),传递字符串参数;

  • H5 → ArkTS:调用鸿蒙方法,获取返回值(如设备类型),并在H5展示。

第一步:编写H5页面(rawfile目录下)

先创建2个文件:index.html(页面结构)和js/index.js(交互逻辑),代码可直接复制。

1. index.html(页面结构)

<!DOCTYPE html><htmllang="zh-CN"><head>    <metacharset="UTF-8">    <metaname="viewport"content="width=device-width, initial-scale=1.0">    <title>ArkTS与H5通信测试</title>    <style>        * { margin: 0; padding: 0; box-sizing: border-box; }        body { padding: 20px; font-size: 16px; line-height: 1.5; }        .container { max-width: 400px; margin: 0 auto; }        .title { text-align: center; color: #2f54eb; margin-bottom: 30px; }        .btn {             display: block; width: 100%; padding: 12px 0;             background: #2f54eb; color: #fff; border: none;             border-radius: 8px; margin: 15px 0; font-size: 16px; cursor: pointer;        }        .info { margin: 20px 0; padding: 15px; border: 1px solid #eee; border-radius: 8px; }        .info-title { font-weight: 600; margin-bottom: 10px; color: #333; }    </style></head><body>    <divclass="container">        <h1class="title">ArkTS ↔ H5 通信测试</h1>        <!-- ArkTS传递给H5的信息展示 -->        <divclass="info">            <divclass="info-title">ArkTS传递的用户信息:</div>            <divid="userInfo">等待接收数据...</div>        </div>        <!-- H5调用ArkTS方法的按钮 -->        <buttonclass="btn"onclick="callArkTSShowToast()">H5调用ArkTS弹窗</button>        <buttonclass="btn"onclick="callArkTSGetDevice()">H5调用ArkTS获取设备类型</button>        <!-- H5接收ArkTS返回值展示 -->        <divclass="info">            <divclass="info-title">ArkTS返回的设备信息:</div>            <divid="deviceInfo">未调用...</div>        </div>    </div>    <!-- 引入交互逻辑JS -->    <scriptsrc="./js/index.js"></script></body></html>

2. js/index.js(H5交互逻辑)

// 1. 接收ArkTS传递的用户信息(ArkTS主动调用此方法)function receiveUserInfo(user) {    const userInfoDom = document.getElementById('userInfo');    // 格式化显示对象数据    userInfoDom.innerText = `姓名:${user.name}\n年龄:${user.age}\n手机号:${user.phone}`;}// 2. H5调用ArkTS的showToast方法(无返回值)function callArkTSShowToast() {    // harmonyBridge是ArkTS注入的全局对象(名称可自定义)    if (window.harmonyBridge) {        // 调用ArkTS的showToast方法,传递参数        window.harmonyBridge.showToast('H5调用了ArkTS的弹窗');    } else {        alert('未检测到ArkTS注入的对象,请检查配置');    }}// 3. H5调用ArkTS的getDeviceType方法(有返回值,用回调接收)function callArkTSGetDevice() {    if (window.harmonyBridge) {        // 调用ArkTS方法,通过回调接收返回值        window.harmonyBridge.getDeviceType((deviceType) => {            const deviceInfoDom = document.getElementById('deviceInfo');            deviceInfoDom.innerText = deviceType;        });    } else {        alert('未检测到ArkTS注入的对象,请检查配置');    }}

第二步:编写ArkTS页面(Index.ets)

这是核心页面,负责加载H5、注入JS对象、实现与H5的双向通信,代码含详细注释,可直接复制运行。

// 导入所需模块(Web组件、弹窗、设备信息)import { webview } from '@kit.ArkWeb';import { promptAction } from '@kit.ArkUI';import deviceInfo from '@ohos.deviceInfo';@Entry@Componentstruct H5CommunicationPage {    // 1. 创建Web组件控制器(用于操作Web组件,如注入JS、执行脚本)    private webController: webview.WebviewController = new webview.WebviewController();    // 2. 定义要注入到H5的对象(H5通过window.harmonyBridge调用此对象的方法)    private harmonyBridge = {        // 方法1:H5调用此方法,显示鸿蒙系统弹窗        showToast: (message: string) => {            promptAction.showToast({                message: message,                duration: 2000 // 弹窗显示时间(毫秒)            });        },        // 方法2:H5调用此方法,获取设备类型(返回值通过回调传递)        getDeviceType: (callback: (deviceType: string) => void) => {            // 获取设备类型(phone/tablet等),通过回调返回给H5            const type = deviceInfo.deviceType === 'phone' ? '手机' : '平板';            callback(`当前设备:${type}(鸿蒙系统)`);        }    };    build() {        Column({ space: 10 }) {            // 标题            Text('ArkTS与H5双向通信实战')                .fontSize(22)                .fontWeight(600)                .margin({ top: 20, bottom: 10 })                .textAlign(TextAlign.Center);            // 3. Web组件:加载本地H5页面            Web({                src: $rawfile('index.html'), // 加载rawfile目录下的index.html                controller: this.webController // 绑定控制器            })            .width('100%')            .height('70%')            // 关键:允许H5执行JS脚本(必须开启,否则通信失败)            .javaScriptEnabled(true)            // 关键:注入JS对象到H5(window.harmonyBridge)            .javaScriptProxy({                object: this.harmonyBridge, // 要注入的对象                name: 'harmonyBridge',      // H5中访问的对象名称(自定义)                methodList: ['showToast', 'getDeviceType'], // 允许H5调用的方法列表                controller: this.webController            })            // Web组件加载完成后,向H5传递数据            .onPageEnd((event) => {                // 4. ArkTS主动调用H5的receiveUserInfo方法,传递用户信息(对象类型)                const userInfo = {                    name: '鸿蒙开发者',                    age: 25,                    phone: '13800138000'                };                // 执行H5的JS方法,传递参数(需将对象转为字符串)                this.webController.runJavaScript(`receiveUserInfo(${JSON.stringify(userInfo)})`);            });            // 按钮:ArkTS主动向H5发送消息(可选,补充场景)            Button('ArkTS向H5发送消息')                .width('80%')                .height(45)                .backgroundColor('#2f54eb')                .fontColor('#fff')                .borderRadius(8)                .onClick(() => {                    // 调用H5的receiveUserInfo方法,传递新数据                    const newUser = {                        name: '新用户',                        age: 30,                        phone: '13900139000'                    };                    this.webController.runJavaScript(`receiveUserInfo(${JSON.stringify(newUser)})`);                });        }        .width('100%')        .height('100%')        .backgroundColor('#f5f5f5');    }}

第三步:运行测试(关键步骤)

  1. 将上述代码复制到对应目录,保存项目;

  2. 选择模拟器(API 10)或鸿蒙真机,点击「运行」按钮;

  3. 运行成功后,会看到如下效果:

    1. 页面加载完成后,H5自动显示ArkTS传递的用户信息;

    2. 点击「H5调用ArkTS弹窗」,鸿蒙系统会弹出提示;

    3. 点击「H5调用ArkTS获取设备类型」,H5会显示当前设备信息;

    4. 点击「ArkTS向H5发送消息」,H5会更新显示新的用户信息。

测试验证:所有操作均能正常响应,说明双向通信成功。若出现失败,可查看下方「避坑指南」。

四、关键细节与避坑指南(必看)

很多开发者复制代码后跑不通,大多是忽略了以下细节,建议逐一检查:

1. 必须开启JavaScriptEnabled

Web组件必须设置javaScriptEnabled(true),否则H5无法执行JS脚本,也无法调用ArkTS注入的对象,通信直接失败。

2. 注入对象的方法列表必须完整

javaScriptProxy的methodList数组,必须包含H5要调用的所有方法(如案例中的['showToast', 'getDeviceType']),否则H5调用时会提示“方法不存在”。

3. 传递对象参数需序列化

ArkTS向H5传递对象、数组等复杂类型时,必须用JSON.stringify()转为字符串,H5接收后可根据需求用JSON.parse()解析(案例中H5直接使用,因JS自动解析了字符串对象)。

4. 回调函数的使用规范

H5调用ArkTS方法并需要返回值时,必须用「回调函数」接收(如案例中的getDeviceType方法),不能直接用return返回——因为H5与ArkTS通信是异步的,直接return无法获取到返回值。

5. 本地H5路径必须正确

Web组件加载本地H5时,src必须是$rawfile('index.html'),且H5文件必须放在resources/rawfile目录下(目录名称不能错),否则会出现“页面加载失败”。

6. 版本兼容性

本文案例基于API 10(HarmonyOS NEXT),若使用API 9及以下版本,部分API会有差异(如webview模块的导入方式),建议升级到API 10开发,避免兼容性问题。

五、拓展场景:在线H5与ArkTS通信

若你的H5是在线页面(如https://xxx.com/h5),只需修改Web组件的src路径,其余代码不变:

Web({    src: 'https://xxx.com/h5', // 在线H5地址    controller: this.webController}).javaScriptEnabled(true).javaScriptProxy({    object: this.harmonyBridge,    name: 'harmonyBridge',    methodList: ['showToast', 'getDeviceType'],    controller: this.webController})

注意:在线H5必须是可信链接(trustedurl),否则可能无法与ArkTS通信,具体可参考鸿蒙官方文档配置可信链接。

六、总结

ArkTS与H5双向通信的核心,是通过Web组件搭建桥梁,用「JS注入」实现H5调用ArkTS,用「脚本执行」实现ArkTS调用H5,两者结合可覆盖所有混合开发场景。

本文提供的案例是最通用、最易落地的实现方式,代码可直接复制跑通,新手也能快速上手。关键是记住3个核心点:开启JS权限、正确注入对象、规范传递参数。

如果需要更复杂的通信场景(如二进制数据传递、频繁消息交互),可以尝试鸿蒙的MessagePorts通信方式,其支持更灵活的双向异步交互,适合复杂业务场景。

福利:本文案例完整源码(含ArkTS+HTML+JS),可直接复制到项目中运行,无需额外修改。为方便大家快速使用,整理了源码压缩包说明,步骤如下:

  1. 新建压缩包,命名为「ArkTS-H5通信案例源码」;

  2. 按本文目录结构,创建entry、src/main/ets/pages、src/main/resources/rawfile、src/main/resources/rawfile/js目录;

  3. 将本文中的Index.ets、index.html、index.js代码分别复制到对应目录下;

  4. 压缩后直接导入DevEco Studio,无需修改任何配置,即可运行测试。

看完本文,你已经掌握了ArkTS与H5通信的核心技巧,快去动手实践吧!

关注我,解锁更多鸿蒙原生开发实战技巧 🚀

最新文章

随机文章