refactor: update README and project structure for native integration and OHOS support

- Enhanced README to clarify native integration methods for Android/iOS and OHOS.
- Updated project structure documentation to reflect changes in native capabilities and dependencies.
- Revised native integration documentation to specify transport methods for Android/iOS and OHOS.
- Documented the current implementation strategy for OHOS, emphasizing the use of MethodChannel for ArkTS.
- Adjusted SDK versioning notes to clarify the separation between Android/iOS and OHOS SDKs.
This commit is contained in:
Guangfei.Zhao
2026-09-02 23:32:16 +08:00
parent 2ed295182b
commit 2704ba5445
4 changed files with 568 additions and 19 deletions
+507
View File
@@ -0,0 +1,507 @@
# Flutter_OH(OpenHarmony)适配 POC 验证报告
> **文档状态:** 部分实施;OHOS 工程生成与 debug HAP 构建已通过
>
> **验证范围:** 现有 Flutter Android / iOS App 基线 → `harmony` 分支 → OpenHarmony 模拟器
>
> **结论边界:** 本轮没有真机。本文只用于判断开发、构建、业务代码复用和集成路径的可行性;不得将模拟器结果表述为鸿蒙生产可用或真机功能已验证。
## 修订历史
| 版本 | 日期 | 状态 | 说明 |
| --- | --- | --- |
| 0.1 | 2026-09-02 | POC 方案已冻结 | 定义范围、验收矩阵、证据要求及决策规则,实施后持续回写实际结果 |
| 0.2 | 2026-09-02 | 部分通过 | 记录 Flutter_OH 3.41.10-ohos-1.0.0 / Dart 3.11.5 的依赖解析和 `main_dev.dart` debug HAP 构建通过;确定首期 ArkTS 采用宿主 `entry` MethodChannel 路径 |
## 0. 结论摘要(实施后填写)
### 0.1 本 POC 回答的问题
本 POC 不回答抽象的“Flutter 能不能做鸿蒙”,而基于 Continental Retail APP 已可运行的 Android / iOS Flutter 基线,回答以下可交付的问题:
1. 能否用 Flutter_OH 在 OpenHarmony 模拟器上完成工程生成、构建、安装、启动和调试?
2. 当前 Dart 业务层、Flutter UI、状态管理、网络、路由和 H5 容器能复用多少;哪些部分必须做 OHOS 专项适配?
3. Dart 公共 API → App 宿主 `entry` → ArkTS 的原生能力链路是否可实现;当前 `native_*` facade 是否适合接入 OHOS?
4. 嵌入 H5 的 WebView / JSBridge 容器能否按现有协议工作?
5. 是否值得进入真机验证与正式鸿蒙适配阶段;需要投入什么改造和持续维护成本?
### 0.2 最终结论卡(实施后填写)
| 项目 | 结果 |
| --- | --- |
| 推荐级别 | `部分通过;尚不足以给出 Conditional Go` |
| 使用的 Flutter_OH 版本 | Flutter `3.41.10-ohos-1.0.0`;Dart `3.11.5` |
| App 基线 | `harmony_3.41.9` 分支;本轮使用 `lib/main_dev.dart` |
| 模拟器基线 | 待记录 DevEco Studio、SDK、设备镜像/API、系统 Build |
| 已证明的能力 | OHOS 工程存在;依赖解析完成;debug HAP 可由 Flutter_OH + hvigor 构建输出 |
| 未证明的能力 | 模拟器运行/热重载、Dart/ArkTS 桥接、真机相机与实体扫码、相册/文件、权限、定位、推送、性能、签名发布、真实 F6 页面 |
| 下一阶段 Gate | 先完成宿主 MethodChannel 探针与模拟器运行,再至少一台目标真机上的原生能力、真实 H5/F6、稳定性与发布验证 |
**结论规则:** 本轮 HAP 构建通过仅证明工具链和 Dart 编译链路可用,不能推导出 App 已可运行或原生能力已接通。没有真机时,即使模拟器中所有计划项通过,本 POC 的最高结论也只能是 **Conditional Go**。只有工具链、代表性业务闭环、JSBridge 和 ArkTS 原生桥接均不存在不可控阻塞时,才能建议进入真机阶段。
### 0.3 已获得的构建证据与未关闭项
在 App 仓库根目录执行 `. .\enable-ohos.ps1`,再进入 `app` 目录执行:
```powershell
flutter build hap --debug -t lib\main_dev.dart
```
依赖解析及 hvigor 构建成功,输出 `app/ohos/entry/build/default/outputs/default/entry-default-unsigned.hap`。该产物是**未签名的 debug HAP**,不等同于已安装、已启动或可发布的完整验证。构建期间仍有 `targetSdkVersion` 未显式配置的 hvigor warning,需在后续 OHOS 工程配置中处理。
首次依赖解析曾因 Dart `3.11.5` 不满足 `^3.12.0`,以及 Flutter 固定 `meta 1.17.0` 与较新 Riverpod generator 的 analyzer 约束冲突而失败。当前 `harmony` 兼容组合为 `flutter_riverpod 3.2.1`、`riverpod_annotation 4.0.2`、`riverpod_generator 4.0.3`、`pigeon 26.3.1`;已对受影响包重新执行 Riverpod codegen 后构建通过。`native_scan` 现存 Pigeon 产物的生成版本标头仍须在后续以锁定的 Pigeon 26.3.1 重新生成或核验,这是生成物完整性检查,不代表 OHOS bridge 已完成。
## 1. 验证对象、范围与边界
### 1.1 POC 对象
- **代码基线:** 已有、可运行的 Android / iOS Flutter App 源码;实施开始前记录一个确定的 Git Commit。
- **工作分支:** 从该 Commit 创建 `harmony` 分支。POC 不直接向主干回灌鸿蒙改造。
- **运行环境:** DevEco Studio 的 OpenHarmony 模拟器;设备型号、系统镜像、API 级别和 Build 均须记录。
- **H5 验证对象:** POC 自带的可控测试页,而不是 F6 正式页面;因此验证的是 App 容器与桥接契约,不代表真实 F6 已完成联调。
- **后端数据:** 如需调用真实接口,只能使用开发/测试环境及测试账号,不使用生产数据。
### 1.2 本轮范围
1. Flutter_OH 工具链、OHOS 工程、依赖解析、编译、安装、启动、调试和热重载可行性。
2. 一个代表性业务闭环:登录/已有会话 → 首页 → 一个真实业务页面,覆盖路由、状态管理、网络、加载态、空态和错误态。
3. 现有 WebView 容器及 JSBridge:可控 H5 页完成握手、H5→App 调用、App→H5 回调、成功/失败回包、未知方法和来源校验。
4. OHOS 原生宿主桥接路径:Dart 公共 API → `native_*` 内部 MethodChannel → `app/ohos/entry` ArkTS 实现 → 成功结果与标准错误回传。
5. 当前依赖与原生能力的 OHOS 兼容矩阵、实际代码改动分类和维护成本评估。
6. Android / iOS 共享代码的回归检查,确认鸿蒙分支没有破坏既有行为。
### 1.3 明确不在本轮结论内
| 能力 | 本轮处理方式 | 原因与后续 Gate |
| --- | --- | --- |
| 相机实拍、二维码/条码实体扫码、车牌/VIN 识别 | 仅验证编译、注册、调用及错误语义 | 模拟器不能替代真实镜头、权限和硬件 SDK;必须真机验证 |
| 相册、文件选择、真实文件上传、运行时权限 | 可记录模拟器观察,但不关闭验收 | 与真实设备系统服务、路径和权限行为有关 |
| 定位、蓝牙、推送、后台任务、埋点/崩溃 SDK | 登记兼容性与实现路径 | 未纳入代表性最小闭环,留待真机专项验证 |
| 真实 F6 页面、票据、账号与业务联调 | 仅验证共同的 JSBridge 契约 | 依赖外部环境、账号和排期 |
| 性能、功耗、包体、机型兼容、商店上架 | 不评估 | 需要真机、正式签名和稳定性测试 |
| 全部业务模块 | 不评估 | 本 POC 只证明一条代表性链路,不能外推为全量适配完成 |
## 2. Flutter_OH 技术现状与调研方法
### 2.1 术语与上游边界
本文中的 **Flutter_OH** 指 OpenHarmony-SIG 维护的 Flutter OpenHarmony 适配分支及其工具链,不是 Google Flutter 主线内置的平台。安装前不得把“`flutter_harmony`”作为既定的工具或包名;应以实际选定的上游仓库、Tag/Commit、安装说明和命令输出为准。
当前调研以 OpenHarmony-SIG 的 `flutter_flutter` 仓库和其环境搭建指南作为一手资料。官方资料说明该仓库是 OpenHarmony Flutter SDK 的来源,并以 `dev` / `master` 等分支说明安装与开发环境;POC 必须锁定实际使用的 Tag 或 Commit,避免“使用最新版”这种不可复现的描述。[Flutter_OH 上游 README](https://gitee.com/openharmony-sig/flutter_flutter/blob/master/README.md?force_mobile=true) · [OpenHarmony Flutter 环境搭建指南](https://gitee.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/03_environment/%E9%B8%BF%E8%92%99%E7%89%88Flutter%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%E6%8C%87%E5%AF%BC.md)
### 2.2 调研记录表(实施前先补齐)
| 维度 | 需要记录的事实 | 证据来源 |
| --- | --- | --- |
| 上游治理 | 维护组织、仓库、许可证、分支策略、发布机制 | 上游仓库 README、LICENSE、Release、治理页面 |
| 版本匹配 | App 当前 Flutter/Dart 与 Flutter_OH Tag/Commit 的对应关系和版本滞后 | `flutter --version`、Git Tag/Commit、构建日志 |
| 社区健康度 | 最近 12 个月提交、Release、Issue/PR 活跃度及关键问题响应 | 上游仓库公开记录,注明采集日期 |
| 构建链路 | Windows、DevEco Studio、OpenHarmony SDK、ohpm/hvigor、Node/Java 的实际要求 | 官方环境文档 + 本地命令输出 |
| 插件生态 | 项目实际依赖的 OHOS 状态与替代方案 | 插件官方仓库/包说明 + 本 POC 构建结果 |
| 可维护性 | 项目团队需自维护的 ArkTS、fork、版本升级和 CI 工作 | POC 改动清单、Issue、风险登记 |
### 2.3 首个硬门禁:SDK 匹配
现有工程文档把 Flutter `3.44.9` 作为未来 OHOS 的兼容窗口,但这个假设不能替代实际验证。POC 首先执行以下判断:
1. 选定 Flutter_OH 的可复现 Tag/Commit;不直接使用会变化的“最新 `dev`”。
2. 记录该 SDK 的 Flutter/Dart 版本,并与 Android/iOS 基线、`pubspec.lock`、插件约束逐项比较。
3. 用未改业务的 App 基线完成依赖解析和 OHOS 编译。
4. 若版本无法兼容,立即记录为阻塞:是需要升级/降级 Flutter、替换依赖,还是当前无可行版本;不得通过私自改动业务代码或跳过插件来宣称“原代码可复用”。
只有该门禁通过,才能进入业务和原生能力验证。
## 3. 基线、分支与环境冻结
### 3.1 分支策略
1. 在实际 App 仓库确认 Android/iOS 基线已构建和测试通过。
2. 记录基线 Commit、当前 Flutter/Dart/FVM 版本、`pubspec.lock`、Android/iOS 构建结果。
3. 由该 Commit 创建 `harmony` 分支;所有 OHOS 改动仅在该分支提交。
4. 不改变既有 Android/iOS 对外业务 API;平台差异收敛在构建配置、`native_*` 内部 transport 与 App 宿主 `ohos/entry` ArkTS 层。Feature、H5 和 Dart entrypoint 不直接调用 OHOS channel。
5. 每次关键里程碑提交均在本文附录登记 Commit、变更摘要、构建命令和结果。
### 3.2 环境锁定表(实施时填写)
| 项目 | 固定值 | 证据 |
| --- | --- | --- |
| Windows 版本 / 架构 | 待填写 | `winver` / 系统信息 |
| DevEco Studio | 待填写 | About 截图 / 版本命令 |
| OpenHarmony SDK / API | 待填写 | SDK Manager 截图 / 配置 |
| 模拟器镜像与 Build | 待填写 | Device Manager / 系统设置截图 |
| Node / Java / ohpm / hvigor | 待填写 | 版本命令输出 |
| Flutter_OH 来源、Tag、Commit | 待填写 | `git remote -v`、`git rev-parse HEAD` |
| Flutter / Dart 版本 | 待填写 | `flutter --version` |
| App 基线 Commit | 待填写 | `git rev-parse HEAD` |
| Pub 缓存、镜像与代理 | 待填写 | 环境变量与配置,脱敏后归档 |
### 3.3 证据归档规则
- 每条验证结论至少附一个可复现命令日志和一个可观察证据(截图、录屏、构建产物或测试输出)。
- 截图、录屏和日志放入 `tech-selection/assets/flutter-oh-poc/<YYYYMMDD>/`;正文只引用相对路径和简短说明。
- 日志中出现 Token、Cookie、账号、内网地址、签名或密钥时,归档前必须脱敏。
- 失败项保留完整报错、最小复现命令、尝试过的版本/方案和最终阻塞判断,不能只写“暂不支持”。
## 4. 可执行教程:从现有 App 跑到鸿蒙模拟器
本章是 POC 的操作手册。请严格按顺序执行:每一步先记录实际命令和输出,再进入下一步。遇到失败时,不要通过删除依赖、注释业务代码或改用空白 Demo 来“跑通”;先把失败作为兼容矩阵的一条证据记录下来。
### 4.1 我们如何分工
| 阶段 | 我可协助完成的工作 | 需要你在本机 / GUI 中完成的工作 | 你需要回传的最小信息 |
| --- | --- | --- | --- |
| 基线确认 | 检查 Git、Flutter、依赖、现有测试与改造差异 | 打开实际 App 源码仓库 | 仓库路径、基线分支/Commit、`flutter --version` |
| Flutter_OH 安装 | 给出命令、检查版本和环境变量、解释报错 | 下载/克隆 SDK,配置本机工具 | Flutter_OH 路径、Tag/Commit、版本输出 |
| DevEco 与模拟器 | 根据截图判断配置与设备识别问题 | 安装 DevEco Studio/SDK,在 Device Manager 创建并启动模拟器 | DevEco 版本、模拟器截图、系统/API Build |
| 项目迁移与构建 | 分析依赖、代码和构建报错,给出最小修复建议 | 在真实 App 仓库执行命令、打开/运行 OHOS 工程 | 完整命令、报错文本、相关文件片段 |
| 运行效果验证 | 制定逐页检查单,核查截图/录屏和日志 | 在模拟器中登录、点击页面、观察 Flutter UI 与调试输出 | 截图/录屏、用例编号、实际/预期差异 |
| 原生能力与 H5 | 审查 ArkTS/Flutter 接口、JSBridge 协议和错误语义 | 触发可在模拟器中操作的调用,保存日志 | 请求/响应、插件日志、模拟器表现 |
### 4.2 开始前:确认 App 基线没有问题
**目标:** 证明后续问题来自 OHOS 接入,而不是原 Android/iOS 基线本身。
在实际 Flutter App 仓库根目录执行。以下命令中的 `<...>` 是你需要替换的占位符;输出不要包含账号、Token 或内网地址。
```powershell
git status --short
git branch --show-current
git rev-parse HEAD
flutter --version
flutter doctor -v
flutter pub get
```
然后执行该仓库既有的静态检查和测试命令;若项目使用 Melos、FVM 或 CI 脚本,优先用项目已有脚本,不能自行换一套命令。记录:
- 当前分支和 Commit;必须是 Android/iOS 已可运行、可复现的基线。
- Flutter、Dart、FVM(如有)和依赖锁文件版本。
- 已通过的检查及失败项;失败项先在原平台澄清,不带入鸿蒙 POC。
**检查点 G-00:** 只有基线可复现时,才创建 `harmony` 分支。
```powershell
git switch -c harmony
git status --short
```
预期结果是当前分支为 `harmony`,工作区没有与本 POC 无关的未提交改动。将基线 Commit 和创建分支后的 Commit 写入“3.2 环境锁定表”。
### 4.3 安装 Flutter_OH:先锁版本,再配置 PATH
**目标:** 不使用模糊的“安装鸿蒙 Flutter”,而是得到一个能追溯到上游 Commit 的 SDK。
1. 阅读上游 README 和环境搭建指南,选择一个候选 Tag 或 Commit。不要直接把当前 Android/iOS Flutter 版本假定为已有对应 OHOS 版本。
2. 在 Windows 上将 Flutter_OH、实际 App 工程及其本地插件放在**同一个磁盘分区**;这是上游 Windows 环境说明中的约束。建议使用空间充足的开发盘,例如 `D:\dev\`。
3. 克隆上游后固定 Commit,再把该 SDK 的 `bin` 临时加入当前 PowerShell 会话的 PATH。示例:
```powershell
$flutterOhRoot = 'D:\dev\flutter_flutter'
git clone https://gitee.com/openharmony-sig/flutter_flutter.git $flutterOhRoot
git -C $flutterOhRoot fetch --tags
git -C $flutterOhRoot checkout <已确认的Tag或Commit>
git -C $flutterOhRoot rev-parse HEAD
$env:Path = "$flutterOhRoot\bin;$env:Path"
flutter --version
flutter doctor -v
```
4. 把 `git remote -v`、最终 Commit、`flutter --version` 和 `flutter doctor -v` 的输出归档到附录 A 的 E-01。只有这些信息完整时,才可以称为“某版本 Flutter_OH 的验证结果”。
**检查点 G-01:** `flutter --version` 必须来自 Flutter_OH 路径,且其 Flutter/Dart 版本与 App 基线及 `pubspec.lock` 的约束不存在立即冲突。若 `pub get` 已经失败,停止向后执行,先在 4.7 的故障表登记版本/依赖问题。
### 4.4 DevEco Studio 与模拟器:由你操作的 GUI 步骤
1. 安装与选定 OpenHarmony SDK 匹配的 DevEco Studio,并通过 SDK Manager 安装目标 API、模拟器镜像、ohpm/hvigor 所需组件。
2. 打开 DevEco Studio 的 Device Manager,创建一个 Phone 模拟器;启动后进入系统设置,截图记录设备型号、OpenHarmony/HarmonyOS 版本、API 级别和 Build。
3. 保持模拟器运行,在 PowerShell 中执行:
```powershell
flutter devices
```
4. 从输出中找到 OHOS 模拟器对应的 `<device-id>`。不要手工猜测设备 ID;将完整输出保存到 E-01。
**检查点 G-02:** `flutter devices` 能列出正在运行的 OHOS 模拟器。若只显示 Windows/Chrome/Android 等设备,先不要执行 `flutter run`;检查模拟器是否真的启动、DevEco SDK/环境变量是否与 Flutter_OH 匹配,再保存 `flutter doctor -v` 和 `flutter devices` 输出供排查。
### 4.5 使用既有 OHOS 工程首次运行
`app/ohos` 已在本轮生成并完成 HAP 构建,**不得重复执行** `flutter create --platforms ohos .`,也不创建新的 Dart `main` 文件。现有环境入口使用 `lib/main_dev.dart`、`lib/main_uat.dart` 和 `lib/main_prod.dart`。
只有在一个新的 `harmony` 工作树中确认 `app/ohos` 缺失、并在运行前后人工审查 Git diff 时,才允许在 `app` 目录执行一次 `flutter create --platforms ohos .`。当前工作树的后续运行与构建从仓库根目录执行:
```powershell
. .\enable-ohos.ps1
cd app
flutter pub get
flutter devices
flutter run --debug -d <device-id> -t lib\main_dev.dart
```
上游 README 公开了 `flutter create --platforms ohos <projectName>`、`flutter devices`、`flutter run --debug -d <device-id>` 和 `flutter build hap --release` 作为 OHOS 工程的创建、设备发现、调试运行和正式构建入口。本 POC 仅在 OHOS 平台目录缺失时使用一次 `--platforms ohos` 生成;任何生成操作前后都要看 Git diff,防止工具意外改写 Android/iOS 配置。[上游 Flutter_OH README](https://gitee.com/openharmony-sig/flutter_flutter/blob/master/README.md?force_mobile=true)
首次运行时你的操作是:
1. 在模拟器中观察 App 是否安装、是否出现启动页、是否白屏/闪退。
2. 在终端保留完整输出;运行中的 Flutter 工具可用 `r` 触发热重载、`R` 触发热重启、`q` 退出。
3. 截取首屏和终端成功日志;若失败,复制第一段真正的 `Error` / `Exception` 及其前后上下文,不要只发最后一行。
首次可运行后执行一次构建验证(若只需复现本轮已通过的编译证据,也可直接执行本命令):
```powershell
flutter build hap --debug -t lib\main_dev.dart
git status --short
git diff --stat
```
**检查点 G-03:** HAP 调试构建已通过;调试运行和热重载仍待执行。只有三者均成功、OHOS 生成物及必要配置可在 `harmony` 分支中解释,且 Android/iOS 文件没有出现非预期改动时,才关闭本检查点。
### 4.6 观察 Flutter 业务代码的实际运行效果
工具链启动成功后,不要马上开始大面积改插件。先用现有业务代码跑完以下最小闭环,借此区分“Flutter 共享代码可以直接复用”与“某个插件阻塞启动”。
1. 在模拟器进入登录页,或按项目已有方式恢复测试登录态。
2. 完成登录后确认首页可显示,依次检查文本、图片、列表、底部导航、路由进入/返回和加载态。
3. 打开一项依赖接口数据的真实业务页面,记录成功、空数据、网络异常或服务端异常时的表现。
4. 对一个纯 Dart/Flutter 的可见文案做极小修改,执行 `r` 热重载,截图记录修改前后;这证明 Flutter 调试循环正常,不等于全量业务已适配。
5. 对每个异常记录:页面、操作、预期、实际、终端日志、截图路径、初步归属(Dart/UI、插件、OHOS 工程、服务端)。
建议回传给我的单条问题格式如下,我可以据此继续分析并给出下一步代码改动:
```text
用例编号:B-03
当前 Commit:<harmony 分支 commit>
操作:登录后点击“库存”进入列表
预期:显示列表;网络失败时显示已有重试页
实际:页面白屏 / 正常 / 报错文案
终端完整异常:<从第一行 Error 到堆栈结束>
截图或录屏:<相对路径>
是否可复现:每次 / 偶发;复现步骤
```
### 4.7 逐个处理依赖,而不是一次性删掉所有插件
首次 `flutter pub get`、`flutter run` 或 `flutter build hap` 很可能暴露不支持 OHOS 的依赖。处理顺序固定如下:
1. 从**第一个阻塞错误**开始,记录包名、版本、错误、调用方和业务影响。
2. 查该依赖的官方仓库/包说明及 OpenHarmony 适配实现;把结论写入 5.2 的兼容矩阵。
3. 判定为“直接复用 / 小幅适配 / OHOS 专项实现 / 替换依赖 / 当前不可行”之一。
4. 对不影响启动的非核心依赖,可临时显式返回 `Unsupported` 以继续验证业务主链路;该临时降级必须在风险台账中登记,不能删除调用或伪造成功。
5. 每完成一个依赖的处理,重新执行 `flutter pub get`、`flutter build hap --debug` 和最小业务闭环,确保没有引入回归。
建议优先级如下:
| 优先级 | 依赖/能力类别 | 原因 |
| --- | --- | --- |
| P0 | Flutter SDK、状态管理、路由、网络、认证、基础存储 | 决定 App 能否启动和承载真实业务 |
| P0 | WebView / JSBridge | 该项目的核心业务链路会嵌入 F6 页面 |
| P1 | 扫码、相机、文件、权限的原生注册与桥接 | 验证可维护的 ArkTS 宿主接入路径;真实硬件留待真机 |
| P2 | 定位、蓝牙、推送、埋点、崩溃上报、弱网 | 本轮记录实现路径与风险,不阻塞代表性闭环 |
### 4.8 验证 WebView 与可控 H5 测试页
本轮不等待 F6 环境。先在 App 内加载一个由 POC 管理的测试页,验证容器与 JSBridge 的安全协议。测试页只用于调试,不能替代真实业务 H5。
1. 沿用 `core_webview` 中已有的目标白名单、来源校验、请求 ID 和回包格式;不要新建一套“POC 专用协议”。
2. 测试页依次发起 `ping` / 获取 App 信息、一个纯 Dart 回包、一个需进入原生适配层的调用,以及一个故意错误的调用。
3. 每个请求在页面上显示 `{ id, method, params }`,并显示来自 App 的成功回包或错误码;App 日志同时记录相同 `id`,以便定位跨端问题。
4. 验证未知方法、类型错误参数和非白名单来源被拒绝,且不会触发原生能力。
5. 再由 App 向 H5 回发一个事件或结果,确认 H5 可关联到原请求。
当你在模拟器中执行时,请对每条 W-01 至 W-06 用例保存一张“请求 + 回包”的截图,并附同一 `id` 的 Flutter 日志。若 WebView 本身无法编译或加载,这本身是 P0 兼容性结论,不要绕过它改为浏览器打开测试页。
### 4.9 验证 Dart → ArkTS 原生宿主桥接
模拟器不能证明相机和扫码可用,但可以验证“项目有能力把原生功能接进来”。按以下最小路径实现和验证:
1. 找到项目当前原生能力的公共 Dart API;架构上始终由 `native_*` 对外暴露,Feature 和 H5 不直接依赖通道实现。
2. 不给 `native_*` 添加 OHOS plugin 声明,也不创建 package 内 `ohos/` 目录。在 `app/ohos/entry/src/main/ets/` 增加宿主桥接注册和 ArkTS 实现;`EntryAbility.ets` 只保留生命周期、Flutter engine 与 bridge 注册。
3. 先实现不使用硬件的 `getPlatformInfo` 或 `echo` 探针:`native_*` 内部 MethodChannel 传入固定参数,ArkTS 返回平台信息/同一参数,Dart 映射为类型化结果。
4. 人为触发一个可预期失败,例如未知操作或硬件不可用;验证 Dart 最终收到标准错误,而不是裸 `PlatformException`、空值或无限等待。
5. 再接通现有 `native_scan` / `native_media` 的入口,只验证 facade 能进入 OHOS 分支、宿主 bridge 可编译,并正确报告“待真机”的硬件不可用状态。
对每一个 Dart ↔ ArkTS 方法,在本文附录或实际宿主实现目录维护一行契约:`channel 名`、`方法名`、`参数`、`返回值`、`错误码`、`Dart 调用点`、`ArkTS 实现文件`。Pigeon 不生成 ArkTS,且不得人工复刻其 `BasicMessageChannel`、自定义 codec 和生成 envelope;这张契约表是手写 MethodChannel 防止接口漂移的最低要求。
### 4.10 常见失败的处理顺序
| 现象 | 优先检查 | 不应采取的做法 |
| --- | --- | --- |
| `flutter` 仍指向官方 SDK | `Get-Command flutter`、PATH 优先级、`flutter --version` | 混用两个 SDK 后继续构建 |
| `flutter devices` 没有 OHOS 模拟器 | DevEco 中设备是否启动、SDK/环境变量、`flutter doctor -v` | 手工伪造 device-id |
| `flutter create` 或构建报版本/引擎错误 | Flutter_OH Commit、Flutter/Dart 版本、同盘约束、完整错误日志 | 强行升级/降级依赖而不记录 |
| 某个插件没有 OHOS 实现 | 兼容矩阵、插件说明、调用影响范围;区分第三方 plugin 与 App 宿主 bridge | 直接删除依赖或把业务调用注释掉 |
| 启动白屏/闪退 | 第一个异常、`EntryAbility` bridge 注册、OHOS 工程配置、最小业务入口 | 只截最后一行错误 |
| WebView 加载失败 | WebView 依赖 OHOS 支持、白名单、控制台/Flutter 日志 | 改用外部浏览器来宣称 H5 通过 |
| 相机/扫码不可用 | 是否为模拟器硬件限制、插件是否已注册、错误码 | 以 mock 成功结果替代真机测试 |
### 4.11 每日回填与协作节奏
每完成一个 Gate,在“附录 A. POC 证据索引”新增一行,并在对应验证表将状态从“待填写”改为“通过 / 部分通过 / 失败 / 待真机”。建议以以下最小包回传,我可以据此继续带着你推进:
1. 当前 `harmony` 分支 Commit 与本次执行的命令。
2. 原始终端输出或脱敏后的完整日志文件。
3. 模拟器截图/录屏,以及对应的用例编号。
4. `git diff --stat`;若改了配置或插件,再附相关文件的 diff。
5. 你对“预期 / 实际”的一句话说明。
我会据此判断是环境问题、Flutter_OH 版本问题、第三方插件问题、共享 Dart 代码问题还是必须留待真机的问题,并给出下一条最小可执行操作,而不是让你一次性排查整套鸿蒙工具链。
## 5. 实施步骤与记录模板
### 5.1 工具链与 OHOS 工程
| 步骤 | 实施动作 | 通过标准 | 实际结果 / 证据 |
| --- | --- | --- | --- |
| T-01 | 按官方资料安装 Flutter_OH 与依赖工具 | `flutter --version` 显示锁定版本;环境变量配置可复现 | 待填写 |
| T-02 | 配置 DevEco Studio、OpenHarmony SDK 和模拟器 | 模拟器可启动并被工具识别 | 待填写 |
| T-03 | 在 `harmony` 分支生成/补齐 OHOS 工程 | 工程结构完整,配置不污染 Android/iOS | 待填写 |
| T-04 | 执行依赖解析和调试构建 | 无阻塞性依赖或编译错误 | 待填写 |
| T-05 | 安装并启动 App | 首屏正常显示,无启动崩溃 | 待填写 |
| T-06 | 调试与热重载 | 可附加调试器;关键 Dart 修改生效 | 待填写 |
### 5.2 代码复用与依赖兼容矩阵
对每个实际依赖和代码层做如下分类,禁止使用笼统的“基本兼容”。
| 分类 | 定义 | 典型处理 |
| --- | --- | --- |
| 直接复用 | 不改源码或仅改构建声明即可运行 | 纯 Dart 模型、业务规则、通用 Flutter UI |
| 小幅适配 | 局部条件分支、配置或 API 替换后运行 | 平台判断、路径、主题或插件初始化 |
| OHOS 专项实现 | 需要新增 ArkTS 宿主实现或已验证的第三方 OHOS 实现 | App `ohos/entry` bridge、特定系统能力 |
| 替换依赖 | 原依赖不支持 OHOS,需使用功能等价方案 | WebView、存储、设备/媒体 SDK 等 |
| 当前不可行 | 没有可控实现路径或风险不可接受 | 记录最小复现、影响范围和 No-Go 条件 |
实施后至少填充以下矩阵:
| 层 / 能力 | 当前实现或依赖 | OHOS 分类 | 改造内容 | 证据 | 风险与责任方 |
| --- | --- | --- | --- | --- | --- |
| Dart 业务模型与 Use Case | 待填写 | 待填写 | 待填写 | 待填写 | 待填写 |
| Flutter UI、主题、路由、Riverpod | 待填写 | 待填写 | 待填写 | 待填写 | 待填写 |
| 网络、认证、错误处理、存储 | 待填写 | 待填写 | 待填写 | 待填写 | 待填写 |
| WebView / JSBridge | `core_webview` | 待填写 | 待填写 | 待填写 | 待填写 |
| 扫码、相机、媒体、文件 | `native_*` 或实际项目实现 | 待填写 | 待填写 | 待填写 | 真机 Gate |
| 权限、定位、推送、蓝牙 | 实际项目实现 | 待填写 | 待填写 | 待填写 | 真机 Gate |
| 日志、埋点、崩溃上报 | 实际项目实现 | 待填写 | 待填写 | 待填写 | 待填写 |
### 5.3 代表性业务闭环
业务闭环选用真实 App 中已经存在的页面和状态流,而不使用新的 Demo 页面伪造成功结果。建议顺序为:
`已有登录态或测试登录 → 首页 → 一项需要接口数据、路由跳转和状态管理的业务页面 → loading / data / empty / error 状态`
| 用例 | 前置条件 | 操作与预期 | 状态 | 证据 |
| --- | --- | --- | --- | --- |
| B-01 启动与会话恢复 | 已配置测试环境 | App 启动后按既有逻辑进入登录或首页 | 待填写 | 待填写 |
| B-02 登录 / 测试会话 | 测试账号或可控会话 | 鉴权成功,凭据和门店上下文按预期处理 | 待填写 | 待填写 |
| B-03 首页与路由 | 已登录 | 首页渲染,进入选定业务页并可返回 | 待填写 | 待填写 |
| B-04 业务数据成功态 | 测试接口可用 | 数据正常加载和展示 | 待填写 | 待填写 |
| B-05 空态与错误态 | 可控响应或测试数据 | 提示、重试和错误映射符合既有约定 | 待填写 | 待填写 |
### 5.4 WebView 与 JSBridge
当前架构将 Embedded H5 及 JSBridge 收敛在 `core_webview`,并由 `native_*` 暴露原生能力;POC 必须沿用该边界,不能为了临时跑通而让 H5 直接调用 ArkTS。现有设计请参见 [Embedded H5 容器与 JSBridge](../flutter-app/10-webview-h5.md) 和 [原生能力集成方式](../flutter-app/07-native-integration.md)。
POC 自带的 H5 测试页必须可显示每次请求的 `id`、`method`、参数、响应及错误码,并覆盖:
| 用例 | 预期 |
| --- | --- |
| W-01 页面加载与桥接就绪 | 白名单页面加载后可确认 App Bridge 已就绪 |
| W-02 H5 → App 合法调用 | 参数通过校验,App 调用现有能力并回传与协议一致的结果 |
| W-03 App → H5 回调 | H5 正确收到事件/结果,`id` 可关联请求与回包 |
| W-04 未知方法 / 非法参数 | 返回明确错误,不执行任何原生能力 |
| W-05 非白名单来源 | 拒绝调用并记录安全日志,不泄露内部信息 |
| W-06 原生能力不可用 | 返回标准化 `UNSUPPORTED`、`PERMISSION_DENIED` 或 `HARDWARE_UNAVAILABLE`,不静默返回空值 |
本节通过只能说明 **App 容器和桥接协议** 可行。F6 真页的页面加载、登录态、文件上传、票据和业务流程仍必须在后续联调中单独验收。
### 5.5 OHOS 原生宿主桥接与 ArkTS 验证
目标是证明项目有可维护的原生接入路径,而不是在没有真机时伪造扫码成功。
1. 在既有 `native_*` 的 Dart facade 内增加 OHOS transport,并在 App 宿主 `ohos/entry` 实现 ArkTS bridge;若基线尚未包含目标能力,可新增仅限 POC 的 `native_capability_probe`,但不能把它伪装成正式扫码实现。
2. 以一个不依赖相机硬件的探针方法验证完整通道:Dart facade 发起调用、`EntryAbility` 注册宿主 bridge、ArkTS 接收参数、返回类型化结果、Dart 映射成功与失败。
3. 以现有 `native_scan` / `native_media` 对外 API 的调用路径验证 facade 分派、宿主 bridge 编译和错误语义;没有硬件时,结果必须标为“待真机”,不得以模拟值代替扫描结果。
4. 记录手写 ArkTS MethodChannel 的 channel 名、方法名、参数/返回值、错误码和接口漂移防护方案;不要求、也不尝试为 Pigeon 生成或手写 ArkTS wire protocol。
5. 不向业务 Feature 暴露 `MethodChannel`、ArkTS 或平台判断;业务和 H5 只能依赖 `native_*` 公共 Dart API。
| 用例 | 验收标准 | 模拟器结论 |
| --- | --- | --- |
| N-01 宿主 bridge 编译与注册 | OHOS 工程可编译;启动日志证明 `EntryAbility` 已注册 bridge | 可关闭 |
| N-02 Dart → ArkTS → Dart | 参数、返回值及异常可在两端对应 | 可关闭 |
| N-03 不支持/硬件不可用错误 | 返回明确、可追踪的标准错误 | 可关闭 |
| N-04 相机与实体扫码 | 真实打开相机、完成识别、处理拒绝权限 | **必须待真机** |
| N-05 文件/相册与权限 | 真实系统服务、路径、取消与拒绝场景 | **必须待真机** |
## 6. 验收、回归与决策
### 6.1 验收状态定义
| 状态 | 使用条件 |
| --- | --- |
| 通过 | 有完整命令、日志和可观察证据,达到预期结果 |
| 部分通过 | 主链路可行,但存在明确限制、人工步骤或未关闭风险 |
| 失败 | 当前版本或实现无法达到验收标准,附最小复现和阻塞原因 |
| 待真机 | 模拟器不能代表真实设备;不记为失败,也不记为通过 |
### 6.2 Android / iOS 回归
- `harmony` 分支的共享 Dart 改动必须继续通过现有静态检查、单元测试、Widget 测试及既有集成测试。
- 若 App 当前已有 Android/iOS CI,记录实施前和实施后的流水线链接或关键输出;若尚无 CI,至少记录本地执行的等价命令与结果。
- 新增 OHOS 条件分支必须覆盖 Android、iOS、OHOS 和未知平台的行为,尤其是不支持能力的显式异常路径。
### 6.3 最终判定
| 判定 | 条件 | 后续动作 |
| --- | --- | --- |
| Conditional Go | SDK 匹配、构建运行、代表性业务、JSBridge、Dart/ArkTS 桥接均通过或有可控适配;硬件能力保留真机 Gate | 进入真机专项验证和正式适配估算 |
| No-Go | 当前基线没有兼容 SDK,或核心业务/桥接/原生插件有不可接受阻塞且无可控替代 | 停止扩面,给出版本调整或替代技术路线建议 |
不得使用“模拟器没问题,所以鸿蒙没问题”作为结论。任何 Conditional Go 必须同时给出下列真机关闭条件:相机、实体扫码、运行时权限、文件/相册、WebView 差异、真实 F6、签名安装、性能稳定性和目标机型验证。
## 7. 成本与风险登记(实施后填写)
### 7.1 成本口径
成本不只统计首轮代码行数,按以下维度记录:
- **一次性接入成本:** OHOS 工程、构建环境、依赖替换、ArkTS 插件、测试页和 CI。
- **业务适配成本:** 共享代码调整、条件分支、UI/渲染差异、接口与存储适配。
- **原生能力成本:** 每个 `native_*` 的 OHOS 实现、权限、SDK 集成、真实设备测试。
- **长期维护成本:** Flutter_OH 跟随 Flutter 主线、插件 fork、ArkTS 接口漂移、社区 Issue 跟进、CI 和发布链路。
代码复用率只有在统计了确定基线和实际差异后才填写;必须同时给出统计范围,不能用一个无范围的百分比代替兼容矩阵。
### 7.2 风险台账
| 编号 | 风险 | 当前证据 | 影响 | 缓解措施 | 关闭条件 | 状态 |
| --- | --- | --- | --- | --- | --- | --- |
| R-OH-01 | Flutter_OH 与当前 Flutter/Dart 基线版本不匹配 | 待验证 | 高 | SDK 匹配作为首个硬门禁 | 基线编译、运行、依赖解析通过 | 待验证 |
| R-OH-02 | 社区分支发布滞后或关键问题依赖外部修复 | 待调研 | 高 | 锁定 Commit、跟踪上游、评估 fork 能力 | 有版本升级与问题响应策略 | 待验证 |
| R-OH-03 | Android/iOS plugin 或三方依赖不具备 OHOS 实现 | 待矩阵验证 | 高 | 逐项分类、优先核心插件、明确替代方案 | 核心原生能力真机通过 | 待验证 |
| R-OH-04 | ArkTS 手写 MethodChannel 产生接口漂移 | 已决定不复刻 Pigeon wire protocol | 中 | 固定 channel 契约、契约测试、`native_*` 公共 API 封装 | Dart/ArkTS 契约自动/人工校验通过 | 开放 |
| R-OH-05 | 模拟器结论与真机不一致 | 已知限制 | 高 | 所有硬件项标记待真机 | 目标真机专项验收完成 | 开放 |
| R-OH-06 | F6 WebView 在 OHOS 的内核与行为差异 | 本轮仅验证可控页 | 高 | 后续真实 F6 联调 | F6 核心流程和 JSBridge 通过 | 开放 |
## 附录 A. POC 证据索引(实施后填写)
| 编号 | 验证项 | 命令/日志 | 截图/录屏/产物 | 代码 Commit | 状态 |
| --- | --- | --- | --- | --- | --- |
| E-01 | SDK 与环境 | 待填写 | 待填写 | 待填写 | 待填写 |
| E-02 | OHOS 构建与安装 | 待填写 | 待填写 | 待填写 | 待填写 |
| E-03 | 业务闭环 | 待填写 | 待填写 | 待填写 | 待填写 |
| E-04 | WebView / JSBridge | 待填写 | 待填写 | 待填写 | 待填写 |
| E-05 | Dart / ArkTS 原生桥接 | 待填写 | 待填写 | 待填写 | 待填写 |
| E-06 | Android / iOS 回归 | 待填写 | 待填写 | 待填写 | 待填写 |
## 附录 B. 真机验收 Checklist(下一阶段)
- [ ] 目标 HarmonyOS / OpenHarmony 真机的签名安装、冷启动、升级与卸载重装。
- [ ] 相机权限:首次授权、拒绝、永久拒绝后的引导、从设置页恢复。
- [ ] 二维码/条码扫描、低光、连续扫码、取消、超时与异常恢复。
- [ ] 车牌/VIN 采集链路及网络异常时的手工降级入口。
- [ ] 相册、拍照、文件选择、取消、无权限、文件路径、压缩与上传进度。
- [ ] 定位、蓝牙、通知/推送、后台恢复及弱网场景。
- [ ] 真实 F6 登录、票据、双向 JSBridge、上传与返回栈。
- [ ] 多台目标机型上的 UI、WebView、性能、功耗、崩溃和日志脱敏。
- [ ] 发布签名、包体、合规声明及目标分发渠道的安装验证。