摘要

将一个已经形成交互闭环的 Web 教学应用迁移到 OpenHarmony,未必意味着立即用 ArkUI 重写全部界面。本项目选择 OpenHarmony Stage 模型 + ArkTS 外壳 + ArkWeb 本地资源的路线,把现有 RISC-V 指令积木、解析器、模拟器和机器状态展示放入 HAP 中运行。本文结合工程结构,说明路线选择、rawfile 同步、JSBridge 预留、真机适配和双版本维护策略。

关键词:OpenHarmony、ArkTS、ArkWeb、rawfile、香橙派 RV2、RISC-V

一、迁移前先回答:哪些内容值得复用

项目的 Web 主线已经具备:

  • 指令积木与操作数槽位;
  • 汇编预览;
  • 解析器和模拟执行;
  • PC、寄存器和存储器展示;
  • 单步、自动执行、暂停和重置;
  • 保存、导入和课堂案例等界面逻辑。

如果立即用 ArkUI 重写,拖拽、吸附、缩放、撤销、动画和案例处理都需要重新实现,两个版本也容易长期分叉。结合比赛周期和教学原型的实际阶段,我们选择先复用稳定的 Web 逻辑,再逐步接入真正需要的原生能力。

二、最终采用的工程结构

整体结构可以概括为:

app/ Web 主线
  ↓ npm run oh:sync
openharmony-port/entry/src/main/resources/rawfile/app/
  ↓ ArkTS Index.ets
ArkWeb 加载 app/index.html
  ↓ OpenHarmonyBridge
运行环境识别、文件能力等原生接口(逐步接入)

真实工程截图显示,OpenHarmony 端采用 entry/src/main/ets/pages/Index.ets 页面入口,同时保留 resourcesmodule.json5syscap.jsonbuild-profile.json5oh-package.json5 等工程文件。原始截图左侧包含本机用户目录,因此公开文章中不直接放出原图,改用下面的目录和代码摘录表达同一事实。

OpenHarmony 页面通过 $rawfile() 加载本地入口:

const WEB_ENTRY = 'app/index.html';

Web({
  src: $rawfile(WEB_ENTRY),
  controller: this.controller
})
  .javaScriptAccess(true)
  .domStorageAccess(true)
  .fileAccess(true)

另一张真实代码截图进一步确认,Index.ets 中不仅启用了 javaScriptAccessdomStorageAccessfileAccess,还配置了名为 OpenHarmonyBridgejavaScriptProxy,方法列表包括 getRuntimeInfosaveCaseloadCase。这与工程源码和本文描述相互对应。

这意味着教学页面随 HAP 打包,不依赖远程网站。对于课堂演示和设备端复现,本地资源比临时网络地址更稳定,也更容易锁定版本。

三、ArkTS 外壳不仅是“打开一个网页”

工程中预留了 OpenHarmonyBridge,当前包含:

  • getRuntimeInfo:告诉 Web 页面当前运行在 OpenHarmony/ArkWeb 环境;
  • saveCase:预留原生保存入口;
  • loadCase:预留原生导入入口。

目前保存和导入还没有完整接入 OpenHarmony 原生文件选择器,因此桥接方法会返回“下一阶段接入”的说明。

javaScriptProxy({
  object: this.bridge,
  name: 'OpenHarmonyBridge',
  methodList: ['getRuntimeInfo', 'saveCase', 'loadCase'],
  controller: this.controller
})

四、为什么要提供同步脚本

当主线代码在 app/,设备端资源又复制到 rawfile/app/ 时,最容易出现的问题是“浏览器版本已经修好,但 HAP 里还是旧代码”。

项目因此提供同步与结构检查流程:

npm.cmd run oh:sync
npm.cmd run oh:diagnostics
npm.cmd run oh:smoke

也可以执行组合命令:

npm.cmd run oh:check

这个流程会同步静态资源、恢复 OpenHarmony 专用桥接和覆盖样式、生成 ArkWeb 诊断页,并检查关键文件是否齐全。当前结构烟测能够检查 28 个文件。实际命令行记录中出现了以下结果:

Core parser and simulator tests passed.
OpenHarmony rawfile smoke test passed. Checked 28 files.

结构烟测不等于 DevEco 构建成功,也不等于香橙派真机运行成功。它的作用是在提交和构建之前,尽早发现资源漏同步、入口文件缺失和依赖路径错误。

五、设备端真正暴露出来的问题

页面第一次打开,并不代表适配已经结束。真机调试中遇到的问题包括:

  1. DevEco SDK 目录结构与 hvigor 预期不一致;
  2. 设备 API Level、Release 类型与工程产物不一致;
  3. HAP 未签名时设备拒绝安装;
  4. 不需要的系统能力进入产物,导致 syscap 校验失败;
  5. ArkWeb 中原生 HTML5 drag/drop 不稳定;
  6. 1024×600 和 1920×1080 屏幕需要不同的布局策略;
  7. OpenHarmony 专用 CSS 后加载,可能覆盖主线新样式。

真实 DevEco Studio 运行日志记录了 signed HAP 发送、bm installaa start 和应用成功启动的完整过程。其中应用包名为 com.riscv.visualteaching。由于原图包含本机绝对路径,公开文章不直接嵌入原图,只保留可验证的脱敏结果:

entry-default-signed.hap
bm install 成功
aa start -a EntryAbility -b com.riscv.visualteaching -m entry
com.riscv.visualteaching successfully launched

六、为什么在 OpenHarmony 端放弃原生 HTML5 拖拽

桌面浏览器中常用的 draggabledataTransfer 和原生 drag/drop 路径,在 RV2 的 ArkWeb 环境里并不稳定。团队测试时曾遇到拖动触发应用闪退。

最终策略是:

  • OpenHarmony 环境禁用原生 HTML5 拖拽;
  • 使用自定义 touchstart/touchmove/touchend 和鼠标事件;
  • 拖动时只移动轻量预览层;
  • 松手后用坐标与目标检测完成写入;
  • 保留“点击积木—点击槽位”的兜底操作;
  • Windows/Web 版不因为设备端降级而失去完整桌面体验。

这样稳定完成一遍教学流程。

七、1080p 教学屏也不是简单放大

从小屏换到 1920×1080 后,问题并不会自动消失。顶部按钮可能过长,日志区域会挤压主工作区,右侧状态面板也可能滚不到底。

项目后续进行了这些调整:

  • 顶部工具栏保留高频控制;
  • 素材栏与编辑区真正左右相邻;
  • 执行日志改为底部抽屉;
  • 右侧机器状态、代码预览和教学说明使用页签;
  • 工作区高度改为 flex 剩余空间,不再依赖 100vh - Npx 的固定估算;
  • OpenHarmony 运行环境标识显示目标屏幕与实际视口。

真机照片中可以看到“OH·RV2·模拟执行”标识,这与项目边界一致:当前已经完成 OpenHarmony 设备端显示和交互验证,但界面中的 GPIO/LED 反馈仍属于软件模拟,不能据此写成真实外设控制。

八、这条路线适合什么阶段

ArkTS + ArkWeb 并不是所有 OpenHarmony 项目的标准答案。它适合:

  • 已有较成熟 Web 交互,需要快速形成设备端原型;
  • 希望保持跨端核心逻辑一致;
  • 原生能力可以分阶段接入;
  • 当前目标是验证场景和教学闭环,而不是立即追求完全原生体验。

如果后续性能、系统集成或无障碍要求提高,再逐步把关键模块原生化,比一开始重写所有交互更可控。

项目链接

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐