定制侠(dingzhixia.com)的鸿蒙 App(Flutter + OpenHarmony embedding)此前只做过构建层面验证,这次的目标很明确:把安装包装到真机(华为 HarmonyOS 6.1,API 23)上跑起来。
项目基本情况:
F:\AiPro\dingzhixia,鸿蒙工程在 ohos/ 子目录F:\flutter_ohos\flutter_flutter(3.41.9+ohos-1.0.2,Dart 3.11.5)hvigorw(绕过 flutter 工具链),ohpm 走本地 no-op shim安装成功,点击启动 → 白屏,什么也没有。进一步观察发现应用实际是启动后秒退,进程都没起来。
这个问题不是一次定位的,而是剥洋葱一样一层层剥出来的。前三次修复都只解决了表层,直到第四次才找到最终根因。
现象:日志报 root isolate 创建失败 / kernel invalid。
根因:本机 PATH 里残留了 D 盘旧版 Flutter SDK(3.27.5-ohos-1.0.1 / Dart 3.6.2),且 PUB_CACHE 指向 D 盘旧缓存。pub get 时旧 Dart 污染了 .dart_tool/package_config.json,生成的 kernel_blob.bin 是 v120 格式,而新引擎(Dart 3.11.5)只认 v127。
修复:用目标 SDK 重跑 pub get 修正 package_config,并在构建脚本里把 PATH 前置加固(node + 目标 dart-sdk/bin + flutter/bin),清理 PUB_CACHE 影响。
现象:修完 SDK 后依旧白屏。
根因:build/ohos/intermediates/flutter/defaultRelease/flutter_assets/ 里有早前构建残留的 URL 编码中文目录(提示词资源),且 manifest/snapshot 文件不完整,release 包打进了残缺的 assets。
修复:删除中间目录整体重建。
现象:重建后 release 包仍走 debug 代码路径。
根因:hvigor 的 --generate-build-profile 只会给工程内模块生成 BuildProfile.ets;ohpm 依赖模块(@ohos/flutter_ohos、flutter_native_arm64_v8a)保持 har 里的默认值:
export const BUILD_MODE_NAME = 'debug';
export const DEBUG = true;
embedder 的 FlutterLoader.isDebugMode() 就是拿它判断模式的。release 包因此误走 debug 的 copyResource 路径,去设备上找 AOT 包里根本不存在的 kernel_blob.bin。
修复:写了 patch_buildprofile.py,构建前按目标模式修补这两个依赖模块的 BuildProfile.ets,构建后恢复默认值,集成进构建脚本。
前三层修完,装机仍然秒退。这次抓到了关键日志:
FlutterNapi --> attachToNative fail, FlutterNapi.hasInit=false
XComFlutterOHOS_Native: Cannot create a FlutterEngine instance in debug mode
without Flutter tooling. To Launch in debug mode, run 'flutter run'...
顺着引擎源码 ohos_main.cpp → ptrace_check.cc 找到判据:
TRACING_CHECKS_NECESSARY 检查:nativeInit 只有收到 --enable-checked-mode 参数(只有 flutter run 才会传)才返回 0;从桌面图标 / hdc 启动没有这个参数 → 返回非 0 → hasInit=false → 引擎创建失败 → 秒退白屏。为什么会混入:ohos/oh-package.json5 的 overrides 写死了 debug 引擎 har(arm64_v8a_debug.har,libflutter.so 38.9MB)。flutter 工具本来会按构建模式复制对应引擎 har 到工程(hvigor.dart 的 copyFlutterRuntime),但我们的构建是直连 hvigorw、绕过 flutter 工具,加上 ohpm 是 no-op shim,overrides 永远指向 debug 引擎。
这也解释了为什么第 3 层的 BuildProfile 补丁无效:那个补丁只改 ArkTS 侧,而引擎的 debug 判据在原生 .so 里,与 ArkTS 无关。
修复:新增 switch_engine.py——release/profile 构建时,把 oh_modules 里 flutter_native_arm64_v8a 模块的 libs/arm64-v8a/libflutter.so 替换为对应模式引擎(release 引擎 16.4MB),首次切换自动把 debug .so 备份到 ohos/.engine_cache/,构建后恢复。集成进构建脚本,与签名切换同一套流程。
对比验证:debug / release 两个 embedding har 的 ArkTS 源码完全一致(diff 验证,只有 BuildProfile / 混淆元数据差异),所以只需换 .so,不用动 ArkTS 层。
排查过程中还解决了两个与白屏无关但同样拦住真机安装的问题:
发布证书签名的包直接 hdc install 会被拒(9568322,not trusted app source)。解法是给 build-profile.json5 增加一套 debug 签名配置(调试证书 + 含本机 UDID 的调试 profile),密钥库复用项目已有的 p12(申请调试证书时复用了同一对密钥提交 CSR,私钥公钥配对验证一致)。切换脚本 switch_signing.py,构建参数第二位传 debug|release。
设备是 HarmonyOS 6.1.0 = API 23,低于工程的 compileSdk 26。直接写 "23.0.0" 被拒(00306042 Specification Limit Violation)。正确写法:API 10-25 必须用 主.次.修订(API) 格式,即 "6.1.0(23)";compile/targetSdkVersion 保持 26.0.0(新 SDK 编译、低版本设备运行,引擎兼容没问题)。
最终产物:发布/entry-default-signed-dbgcert-rel4-20261020.hap(36.8MB,AOT release + release 引擎 + 调试签名):
| 验证项 | 结果 |
|---|---|
| hap 内 libflutter.so | 16.4MB release 引擎(此前是 38.9MB debug 引擎) |
| 安装 | hdc install -r 成功(注意必须用相对路径) |
| 启动 | 登录页完整渲染:品牌 logo、账号密码输入、三方登录按钮齐全 |
| 稳定性 | 进程持续运行 6 分钟以上无退出;锁屏唤醒后重启 UI 仍正常 |
| 日志 | 无 debug 模式报错、无 attachToNative 失败,仅剩无害的 fallback 字体警告 |
这次踩的坑大多源于「绕过 flutter 工具链直连 hvigorw」,把要点沉淀下来:
主.次.修订(API),API 26+ 才用纯三段式。hilog -x 里 FlutterNapi / Native 引擎相关标签,比盲目翻源码快得多。
还没有评论,登录后来说两句。