从零开始写 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
相关推荐
IT_陈寒29 分钟前
Vite静态资源路径这个大坑害我调了一下午
前端·人工智能·后端
狗哥哥35 分钟前
分享下我的读书清单
前端
合天网安实验室1 小时前
Log4J2 FilteredObjectInputStream RCE 漏洞分析
前端·黑客
两点王爷1 小时前
使用 GeoServer 发布 SHP 数据并在前端页面加载显示
前端
lhldsg1 小时前
全民健身解决方案软件开发实战:从架构设计到部署指南
java·前端·数据库·小程序
四六的六1 小时前
让 AI 自己去点后台页面,它把我们的库存点没了
前端·人工智能·agent·个人开发·ai编程·ai产品·ai前端
两点王爷1 小时前
Java 与前端加载 MVT 数据:从服务端切片到浏览器渲染
java·前端·状态模式
小码过河.1 小时前
oceanbase中zone和observer、分区表之间关系
前端·数据库·oceanbase
平头哥技术团队3 小时前
Day 16 | 用 ul、ol、li 一个标签,把散资料收成有序的技能清单页
开发语言·前端·html·html5
代码青铜z3 小时前
不会写代码做小程序,模板开发和AI 编程靠谱吗?创业前先看这 5 件事
前端