从零开始写 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
相关推荐
lichenyang4531 小时前
从 Vite 空项目到 AIGC 图片工作台:我如何打通生图、任务轮询、生成库与 Canvas 动态特效
前端·人工智能
泡沫冰@1 小时前
上章节中文件的讲解
前端·网络·nginx
进击的丸子2 小时前
APP人脸识别增值版Harmony Demo实操与关键代码解析
前端·程序员·harmonyos
a1117762 小时前
唯美花朵风格的黑胶唱片音乐播放器
前端·css·css3
Hilaku2 小时前
工作 5 年后,决定你薪资上限的究竟是什么?
前端·javascript·程序员
爱分享的程序猿-Clark2 小时前
【前端分享】vue3 有 keep-alive属性吗?
前端
Revolution612 小时前
页面更新后为什么出现 Loading chunk failed:旧页面如何请求了已删除的构建产物
前端·面试·前端工程化
JavaGuide2 小时前
GitHub 9.8 万 Star!把整个代码仓库变成知识图谱,这个 AI Coding 工具太适合 Claude Code / Codex 了
前端·后端·ai编程
hunterandroid3 小时前
[鸿蒙从零到一] HarmonyOS 通知与提醒实战:消息发布、点击跳转与定时触达
前端
Lxinz3 小时前
vscode调试ts代码思路
前端