从零开始写 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
相关推荐
IMPYLH17 分钟前
HTML 的 <title> 元素
前端·javascript·html
开开心心就好20 分钟前
视频模糊怎么修复?免费工具支持批量处理
java·前端·人工智能·智能手机·pdf·excel
变与不变80621 分钟前
jspost请求详解
前端·javascript
派小心.1 小时前
React StrictMode埋点双执行的验收方法
前端·前端框架
IT_陈寒1 小时前
Python的GIL锁让我把多线程代码全重写了!
前端·人工智能·后端
百度一下吧1 小时前
umi后台管理项目实战:从工程搭建到生产构建
java·前端·javascript
派小心.1 小时前
App埋点排查:iOS冷启动事件漏报先看初始化还是上报
前端·数据分析
事圆则缓1 小时前
Flutter 状态管理框架对比(六):同一个购物车,四种方案怎么落地?
前端·javascript·flutter
peter67682 小时前
css揭秘-背景和边框
前端·css
派小心.2 小时前
小程序埋点验收:自定义事件上报后页面参数怎么核对
前端·数据分析