HarmonyOS + Cordova 工程搭建与目录结构:从零到跑通 & 常见报错排查


适用人群:刚接触鸿蒙混合开发,希望基于 @magongshou/harmony-cordova 快速搭建工程、跑通示例,但经常遇到"白屏、资源 404、Hostname 配错"等问题的同学。

文章以"问题解决"为主,代码占比约 3/10,更多篇幅用于解释工程结构和排错思路。


1. 整体框架先搞清楚

在排查任何问题之前,先要知道 工程里有哪些层、谁加载谁:

  • 原生层(ArkTS / Harmony 工程)
    • EntryAbility:应用入口,初始化 Web 引擎,加载首屏 pages/Index
    • Index.ets:ArkUI 首屏,承载 MainPage Cordova 容器。
  • 容器层(Cordova ArkTS 实现)
    • MainPage.ets:封装 ArkWeb WebView + Cordova 初始化 + 资源拦截。
    • Cordova 插件体系:CordovaPluginPluginEntry 等。
  • Web 前端层(rawfile 静态资源)
    • rawfile/www/index.html:2048 入口页。
    • css/js/:样式与游戏逻辑。

1.1 框架结构图

EntryAbility Index.ets MainPage Cordova 容器 ArkWeb WebView rawfile/www/index.html css/style.css js/app.js

1.2 目录结构速览(简化)

text 复制代码
entry/
  src/main/ets/
    entryability/EntryAbility.ets
    pages/Index.ets
cordova/
  src/main/ets/components/MainPage.ets
  src/main/ets/components/CordovaPlugin.ets
  src/main/resources/rawfile/www/
    index.html
    css/style.css
    js/app.js

理解这张图后,很多"找不到文件""白屏"问题就有了排查顺序:

  1. 先看 原生是否加载到 Index
  2. 再看 Index 是否渲染了 MainPage
  3. 再看 MainPage 是否计算出正确的 src URL
  4. 最后看 rawfile/www 是否有对应资源

2. 工程搭建中的典型问题一览

2.1 问题:启动后直接白屏,日志里几乎没 Web 输出

现象

  • App 能启动,但始终是纯色背景。
  • Logcat/IDE 日志中能看到 EntryAbility.onCreate,但很少有 Web 相关日志。

排查思路(整体 Flow)
否 是 否 是 否 是 启动后白屏 EntryAbility 是否执行 initializeWebEngine? 补充初始化 Web 引擎 windowStage.loadContent 是否加载 pages/Index? 检查路由/页面路径 Index.build 中是否渲染 MainPage? 修复 Index.ets UI 构建 进入 MainPage 初始化流程

2.2 关键代码:EntryAbility 正确初始化 Web 引擎

ts 复制代码
// entry/src/main/ets/entryability/EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { webview } from '@kit.ArkWeb';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    // 初始化 ArkWeb 引擎
    webview.WebviewController.initializeWebEngine();
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        // 这里可以增加日志,方便排查
        return;
      }
    });
  }
}

排查要点

  • 确认 initializeWebEngine() 是否被调用。
  • 确认 loadContent('pages/Index')路径大小写 无误(ArkTS 区分大小写)。

3. Hostname / indexPage 配置导致的"资源 404"

在本项目的 Cordova 实现中,MainPage 会根据 Cordova 配置来计算最终加载 URL:

ts 复制代码
// 逻辑示意(简化版)
aboutToAppear() {
  // ... InitCordova 返回 JSON 字符串
  let preferences: string = cordova.InitCordova(/* 参数省略 */);
  let jsonConfig: object = JSON.parse(preferences) as object;
  let arrayObject: Array<object> = jsonConfig['preferences'];

  arrayObject.forEach((obj: object) => {
    if (obj['name'] === 'Hostname') {
      this.strTmpUrl = obj['value'];
    }
  });

  if (this.indexPage == '') {
    this.src = 'https://' + this.strTmpUrl + '/www/index.html';
  } else {
    // 自定义入口
  }
}

3.1 常见错误 1:Hostname 与实际不匹配

症状

  • 运行时控制台里出现类似:
    • GET https://example.com/www/index.html 404
  • 但你的实际 Hostname 并不是 example.com

解决步骤

  • 找到 Cordova 的配置(通常在 config.xml 或等效配置)中:
    • 确认 Hostname 与代码一致,例如 localhostharmony.cordova.local 等。
  • 若不确定,可在 MainPage.aboutToAppear 中临时打印 this.src
ts 复制代码
console.log('[MainPage] final src = ' + this.src);

最佳实践:开发阶段可以统一用类似:

  • Hostname = "harmony.cordova.local",方便识别。

3.2 常见错误 2:误以为可以直接改 this.src 为本地 file URL

错误示例

ts 复制代码
// ❌ 错误示意:直接写 file://
this.src = 'file:///data/storage/el2/base/files/www/index.html';

在 Cordova 实现中,已经通过自定义协议 + 资源拦截 帮你处理了 rawfile 映射,直接使用 https://{Hostname}/www/index.html 即可,不需要手动拼 file 路径。


4. rawfile 目录与资源路径检查

若 URL 是正确的 https://{Hostname}/www/index.html,但仍报 404 或部分资源丢失,通常出在 rawfile 目录结构

4.1 检查最终打包路径

构建后,Web 静态资源应位于:

text 复制代码
cordova/src/main/resources/rawfile/www/
  index.html
  css/style.css
  js/app.js

容易出错的点

  • www 目录层级错了,比如:rawfile/index.html 而不是 rawfile/www/index.html
  • CSS/JS 的相对路径写成了绝对路径,导致找不到资源。

4.2 index.html 中的资源路径写法

推荐写法(来自项目实际代码):

html 复制代码
<link rel="stylesheet" href="css/style.css" />
...
<script src="js/app.js"></script>

不要写成类似:

html 复制代码
<!-- ❌ 容易出错的写法 -->
<link rel="stylesheet" href="/css/style.css" />
<script src="/js/app.js"></script>

因为 /css/style.css 会被当成根路径,而不是相对于 www/


5. Index.ets 未正确渲染 MainPage 的问题

即使 EntryAbility 和资源路径都 OK,如果 Index.ets 没有渲染 MainPage,Web 仍然不会出现。

5.1 正确的 Index.ets 写法(节选)

ts 复制代码
// entry/src/main/ets/pages/Index.ets
import {
  MainPage,
  pageBackPress,
  pageHideEvent,
  pageShowEvent,
  PluginEntry
} from '@magongshou/harmony-cordova/Index';

@Entry
@Component
struct Index {
  cordovaPlugs: Array<PluginEntry> = [];

  onPageShow() { pageShowEvent(); }
  onBackPress() { pageBackPress(); return true; }
  onPageHide() { pageHideEvent(); }

  build() {
    RelativeContainer() {
      MainPage({
        isWebDebug: false,
        cordovaPlugs: this.cordovaPlugs
      });
    }
    .height('100%')
    .width('100%')
  }
}

排查 checklist

  • 是否导入了 MainPage
  • build() 中是否真的调用了 MainPage
  • 是否给 MainPage 足够的宽高(100%)?

6. 总结:从框架到问题排查的路线图

我们把本文的排查路径整理成一张图,方便你在遇到问题时快速定位:
否 是 否 是 否 是 否 是 App 启动异常/白屏/404 EntryAbility 初始化正常? 检查 initializeWebEngine & loadContent Index.ets 是否渲染 MainPage? 补充 MainPage & 生命周期透传 MainPage 计算的 src 是否正确? 检查 Hostname & indexPage rawfile/www 目录结构正确? 调整 www/ 目录与资源路径 进一步检查插件/拦截逻辑

建议用法

  • 新建工程或迁移旧 Web 项目时,对照本文一节一节检查。
  • 遇到白屏时,按"入口 → Index → MainPage → rawfile"顺序排查,不要一上来就怀疑 Web 代码。

有了这篇"地基"文章,你在阅读本仓库其他高级主题(自定义插件、性能优化等)时,会更清楚每一层到底在干什么,也更容易在出现问题时快速定位到具体环节。

相关推荐
Georgewu3 小时前
【HarmonyOS 6】在UI控件上滑动也会触发onClick点击事件?
harmonyos
Georgewu4 小时前
【HarmonyOS 6】为什么getContext 废弃,使用getHostContext说明
harmonyos
爱笑的眼睛114 小时前
HarmonyOS应用崩溃捕获与上报:分布式场景下的深度实践与优化
华为·harmonyos
A懿轩A5 小时前
【2025版 OpenHarmony】GitCode 口袋工具 v1.0.1 更新发布:Flutter + HarmonyOS 封装导航栏进行跳转
flutter·harmonyos·openharmony·gitcode·开源鸿蒙
不羁的木木8 小时前
【开源鸿蒙跨平台开发学习笔记】Day01:React Native 开发 HarmonyOS-环境搭建篇
学习·开源·harmonyos
lqj_本人8 小时前
鸿蒙与Qt的双线程模型:主线程与UI线程的博弈
qt·ui·harmonyos
御承扬8 小时前
鸿蒙原生系列之拖拽事件
华为·harmonyos·拖拽事件·ndk ui
不爱吃糖的程序媛8 小时前
开源鸿蒙 Cordova 设备信息插件开发详解
华为·开源·harmonyos
A懿轩A12 小时前
【2025最新】Flutter 编译开发 鸿蒙HarmonyOS 6 项目教程(Windows)
windows·flutter·华为·openharmony·开源鸿蒙