从零开始写 HarmonyOS Web 容器:先让 ArkWeb 加载本地 H5

从零开始写 HarmonyOS Web 容器:先让 ArkWeb 加载本地 H5

项目地址:github.com/lichenyang5...

本文是 MiniAppRuntime-Harmony 系列的第二篇,重点讲第一阶段:ArkWeb 加载本地 H5。

说明:本文只讨论个人开源项目实现,全部基于公开能力,不涉及任何内部源码或非公开实现。

1. 先不要急着写 JSBridge

很多人做 Web 容器,第一反应是写通信:

text 复制代码
H5 调 ArkTS
ArkTS 回调 H5

但是我建议第一步不要做这个。

第一步只做一件事:

让 ArkWeb 稳定加载本地 H5 页面。

原因很简单:

如果页面加载本身就有问题,后面 JSBridge 出问题时,你会不知道是 Web 容器问题,还是通信问题。

所以我的第一阶段拆成这样:

text 复制代码
阶段 1:ArkWeb 加载本地 HTML
阶段 2:H5 通过 JavaScriptProxy 调 ArkTS
阶段 3:ArkTS 通过 runJavaScript 回调 H5
阶段 4:引入 Dispatcher / Registry
阶段 5:接入真实系统能力

这样每一步都能独立验证。

2. H5 放在哪里

本项目把 H5 Demo 放在 rawfile 目录:

text 复制代码
entry/src/main/resources/rawfile/web/
  index.html
  js/
    myascf.js
    demo.js
  css/
    demo.css

为什么选择 rawfile?

因为这是一个本地 Demo,不依赖网络。

我们要验证的是容器能力,不是远程页面加载能力。

本地 H5 的好处是:

  • 不需要服务器;
  • 不需要网络权限;
  • 页面内容固定;
  • 方便定位问题;
  • 适合做最小闭环。

3. ArkTS 侧 Web 页面

Index.ets 的核心就是一个 Web 组件。

大致结构如下:

ts 复制代码
import { webview } from '@kit.ArkWeb'

@Entry
@Component
struct Index {
  private controller: webview.WebviewController = new webview.WebviewController()

  build() {
    Column() {
      Web({
        src: $rawfile('web/index.html'),
        controller: this.controller
      })
      .width('100%')
      .height('100%')
    }
    .width('100%')
    .height('100%')
  }
}

这一步只关心页面是否能显示。

不要在这里写业务逻辑,也不要把 Toast、Dispatcher、Registry 都堆到页面里面。

页面是壳。

运行时能力应该放到 runtime/ 目录。

4. H5 页面

index.html 只需要做一件事:展示页面,并提供一个按钮。

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>MiniAppRuntime Harmony Demo</title>
  <link rel="stylesheet" href="./css/demo.css" />
</head>
<body>
  <main class="page">
    <h1>MiniAppRuntime Harmony</h1>
    <p>当前阶段:ArkWeb 加载本地 H5 Demo</p>

    <button id="btn-test">点击测试</button>

    <pre id="log"></pre>
  </main>

  <script src="./js/myascf.js"></script>
  <script src="./js/demo.js"></script>
</body>
</html>

这个页面不用复杂。

越简单越好,因为它只是用来验证 Web 容器。

5. 为什么先写 myascf.js 空壳

第一步里,myascf.js 可以只是一个空壳:

js 复制代码
window.myascf = {
  send: function(action, params) {
    console.log('[myascf.send]', action, params)
  }
}

这看起来没什么用,但它有一个作用:

先把 H5 侧的公开调用入口定下来。

后面所有能力都从这里发起:

js 复制代码
window.myascf.send("ui.showToast", { message: "hello" })

也就是说,第一步虽然不通信,但已经确定了开发者侧 API 的形状。

6. 验收标准

这一阶段的验收标准很简单:

  • 应用可以启动;
  • ArkWeb 可以显示本地页面;
  • 页面可以加载 CSS;
  • 页面可以加载 JS;
  • 点击按钮可以输出 console 日志;
  • 不要求 H5 调 ArkTS;
  • 不要求 ArkTS 回调 H5。

把验收标准写清楚很重要。

因为框架开发最怕"顺手多做一点"。

多做一点,往往就会把边界搞乱。

7. 下一步做什么

页面跑起来之后,下一步才是通信:

text 复制代码
H5
→ window.myascf.send
→ window.MyASCFNative.postMessage
→ JavaScriptProxy.postMessage
→ ArkTS

这一阶段只解决一个问题:

H5 的 JSON 字符串能不能稳定送到 ArkTS?

等这个问题解决,再谈 Dispatcher、Registry、Biz、Imp。

项目地址:

text 复制代码
https://github.com/lichenyang5/MiniAppRuntime-Harmony
相关推荐
kyriewen1 小时前
一个看不见的撇号,让Claude Code追踪了中国开发者三个月
前端·ai编程·claude
莫生灬灬1 小时前
DY联系人聊天Web面板支持获取联系人/聊天记录/发送消息
前端·chrome·websocket·c#
郑州光合科技余经理1 小时前
海外外卖平台源码改造实战——多语言核心代码实现
java·开发语言·前端·后端·mysql·架构·php
一tiao咸鱼2 小时前
前端转 agent # 02 - FastAPI 框架入门与原理
前端·python
wanghowie2 小时前
LangGraph4j 落地(二)— ReAct 多步工具与 trace 扩展
前端·react.js·前端框架
大家的林语冰2 小时前
Rust 再次打败 Go,Astro 7 首发,什么叫“万物皆可锈化“!
前端·javascript·性能优化
lichenyang4532 小时前
H5 如何调用 ArkTS:JavaScriptProxy、requestId 和 Promise 回调
前端
lichenyang4532 小时前
我在 HarmonyOS 上写了一个轻量级小程序运行时:从 Web 容器到 JSBridge
前端
雪隐2 小时前
用Flutter做背单词APP-02我画了设计稿,然后让AI帮我设计了数据库(顺便聊了会天)
前端·人工智能·后端