Harmony 3.41.9 #1

Merged
guangfei.zhao merged 5 commits from harmony_3.41.9 into main 2026-09-03 16:58:35 +08:00
4 changed files with 64 additions and 18 deletions
Showing only changes of commit d786fc31ff - Show all commits
+12
View File
@@ -93,6 +93,18 @@ melos run format # dart format --set-exit-if-changed
melos run test # flutter test --coverage
```
### OHOS(`harmony` 分支)构建
`enable-ohos.ps1` 只为当前 PowerShell 会话注入 Flutter_OH、ohpm、hvigor 与 DevEco 环境变量,不修改用户或系统 PATH。先在仓库根目录执行,再进入 `app` 使用已有的开发环境入口构建:
```powershell
. .\enable-ohos.ps1
cd app
flutter build hap --debug -t lib\main_dev.dart
```
构建产物为未签名 debug HAP:`app/ohos/entry/build/default/outputs/default/entry-default-unsigned.hap`。这不会创建新的 Dart `main` 文件;现有环境入口仍是 `lib/main_dev.dart`、`lib/main_uat.dart` 和 `lib/main_prod.dart`。HAP 编译通过不代表 ArkTS 原生桥接、扫码或真机安装已经完成,边界见 [docs/07-native-integration.md](docs/07-native-integration.md)。
`analyze` 带 `--fatal-infos`。不加等于没加 lint——绝大多数 riverpod_lint 规则
报的是 info 级。
+7 -5
View File
@@ -30,7 +30,7 @@ conti-app/
feature_analytics/ # 经营分析:对账单、核销收入、返利、报表
feature_profile/ # 个人中心:地址、热线、客服
feature_scan/ # 扫码业务入口(VIN/车牌/二维码/条码 → 分发到对应业务)
native_scan/ # 原生插件包:扫码能力(android/ios 两端实现)
native_scan/ # 原生能力 Dart facade;Android/iOS 插件,OHOS 实现在 App entry
native_media/ # 相机、相册、文件选择/上传
native_device/ # 拨号、设备信息、权限申请
```
@@ -42,7 +42,7 @@ conti-app/
- `app` 可以依赖所有 `core_*` 和 `feature_*`。
- `feature_*` **只能**依赖 `core_*` 和 `native_*`,**不能**相互依赖(`feature_purchase` 的 `pubspec.yaml` 里不允许出现 `feature_inventory` 的 path dependency)。
- `core_*` 可以依赖 `native_*`(`core_webview` 的 JSBridge 需要调起扫码/相机/上传)。
- `native_*` 只依赖 Flutter SDK 和 [Pigeon](https://pub.dev/packages/pigeon) 生成的代码,不依赖任何 `core_*` / `feature_*`——保证原生插件包可以脱离业务单独编译、单独测试(详见 [07-native-integration.md](./07-native-integration.md))。
- `native_*` 只依赖 Flutter SDK 与自身的跨平台 transport,不依赖任何 `core_*` / `feature_*`。Android/iOS transport 使用 [Pigeon](https://pub.dev/packages/pigeon) 生成代码;OHOS transport 可在 facade 内使用 `MethodChannel`,其 ArkTS 落在 App 宿主 `ohos/entry`,仍不得泄漏给业务层(详见 [07-native-integration.md](./07-native-integration.md))。
`core_*` 之间原则上不互相依赖,允许的例外只有下面三条,多一条都要走评审:
@@ -74,7 +74,7 @@ conti-app/
- `core_xxx`:基础设施层,不含具体业务逻辑。
- `feature_xxx`:对应一个业务域(多数是原来的某个小程序,也有全新的,如首页工作台)。
- `native_xxx`:原生能力插件包,首版含 `android/`、`ios/` 两套原生实现目录(OHOS 不在首版范围,见 [07-native-integration.md](./07-native-integration.md))。
- `native_xxx`:业务侧唯一可依赖的原生能力 facade。Android/iOS 原生实现位于插件包;`harmony` 分支首期 OHOS ArkTS 实现位于 App 宿主的 `ohos/entry`,见 [07-native-integration.md](./07-native-integration.md)。
## SDK 版本基线
@@ -82,8 +82,11 @@ conti-app/
|---|---|---|
| Flutter | **3.44.9** | 用 [FVM](https://fvm.app/) 锁定,仓库根目录提交 `.fvmrc` |
| Dart | 随 Flutter 3.44.9 附带(3.12.x) | 具体号以 `flutter --version` 实测为准;`environment: sdk: ^3.11.0` 对整个 3.12.x 都成立 |
| Flutter_OH(仅 `harmony`) | **3.41.10-ohos-1.0.0 / Dart 3.11.5** | 仅用于 OHOS 构建;由 `enable-ohos.ps1` 临时注入当前 PowerShell PATH,不能替换 Android/iOS 的 FVM SDK |
**为什么不跟最新 stable(3.47.0 / Dart 3.13.0,2026-08-12 发布)**:鸿蒙(OpenHarmony)的 Flutter 分支适配落后于官方 stable 一段时间,虽然 OHOS 不在首版范围(见 [07-native-integration.md](./07-native-integration.md) 的「OHOS 后续演进」),但 SDK 基线要为后续接 OHOS 留出兼容窗口,所以刻意停在 3.44.9 而不是追最新。这条约束在决定升级 Flutter 版本时必须重新评估,不要因为"新版本有新特性"就单方面升。
**OHOS SDK 边界**:OpenHarmony 的 Flutter 分支与官方 stable 不同步。Android/iOS 仍以 FVM 锁定的 Flutter 3.44.9 为基线;`harmony` 分支已用 Flutter_OH 3.41.10-ohos-1.0.0 / Dart 3.11.5 完成 HAP 编译验证。两套 SDK 不可混用,任一侧升级都必须重新验证依赖解析、生成代码和对应平台构建(见 [07-native-integration.md](./07-native-integration.md))。
**未来收敛条件**:Flutter_OH 上游文档计划在 **2026 年 9 月**提供 Flutter **3.44.x / Dart 3.12.x** 对齐版本;发布实际 Tag/Commit 可获取后,可评审将 `harmony` 与 Android/iOS 收敛到同一 SDK 基线。计划日期或版本号相同都不是自动放行条件;必须重新完成依赖解析、Riverpod/Pigeon 生成物核验、HAP 构建及真机原生能力验证后才能切换。
**为什么必须用 FVM 锁**:monorepo 里各人本地 Flutter 版本不一致,会导致同一份代码有人 `flutter analyze` 过、有人不过,生成代码(`build_runner` 产物)也可能不一致——这类问题排查成本远高于装一次 FVM。CI 也用 `.fvmrc` 里的版本,保证本地和流水线一致。
@@ -263,4 +266,3 @@ dart pub global activate melos
- [Pigeon | Dart package](https://pub.dev/packages/pigeon)
- [Drift | Dart package](https://pub.dev/packages/drift)
- [Lerna(JS 生态对标工具)](https://lerna.js.org/)
+43 -11
View File
@@ -2,13 +2,13 @@
## 决策
原生能力(扫码、支付、蓝牙等)统一封装成独立的 `native_*` Dart package(结构见 [01-project-structure.md](./01-project-structure.md)),跨语言接口用 **[Pigeon](https://pub.dev/packages/pigeon)**(`^27.3.0`,2026-08 快照)生成,不手写裸 `MethodChannel`/`invokeMethod` 字符串调用。
原生能力(扫码、支付、蓝牙等)统一由独立的 `native_*` Dart package 暴露稳定公共 API(结构见 [01-project-structure.md](./01-project-structure.md))。**Android/iOS** 跨语言接口使用 [Pigeon](https://pub.dev/packages/pigeon)(锁定 `26.3.1`)生成;`harmony` 分支的首期 **OHOS** 实现是经过约束的例外:`native_*` 内部通过手写 `MethodChannel` 调用 App 宿主 `app/ohos/entry` 中的 ArkTS,而不是将 OHOS 再包装成独立 Flutter plugin。
## 依赖
```yaml
dev_dependencies:
pigeon: ^27.3.0
pigeon: 26.3.1
```
## 包结构规则
@@ -32,7 +32,28 @@ native_scan/
Classes/NativeScanPlugin.swift # 手写:插件注册入口
```
首版只有 `android/` 和 `ios/`(OHOS 不在首版范围,见文末「OHOS 后续演进」)。
插件包中的原生目录目前只有 `android/` 和 `ios/`;这不是遗漏。OHOS 的首期 ArkTS 实现位于宿主 App 的 `app/ohos/entry`,见下节。
### 平台实现归属:Android/iOS 插件,OHOS 宿主桥接
```
feature_* / core_webview(JSBridge)
↓ 只依赖公共 Dart API
native_scan
┌─────────┴──────────┐
│ │
Android / iOS OHOS(harmony)
Pigeon + plugin 手写 MethodChannel
Kotlin / Swift ↓
app/ohos/entry ArkTS
```
| 平台 | Dart 到原生 transport | 原生代码归属 | 原因 |
| --- | --- | --- | --- |
| Android / iOS | Pigeon 生成的强类型桩代码 | `packages/native_scan/android`、`ios` | 复用成熟的 Flutter plugin 注册和 Kotlin/Swift 生成链路 |
| OHOS(首期) | `native_scan` 内部的手写 `MethodChannel` | `app/ohos/entry/src/main/ets/` | Pigeon 不生成 ArkTS;不手抄其 `BasicMessageChannel` / 自定义 codec 协议,降低漂移风险 |
这不会增加 Dart `main` 文件,也不会新增 HAP module。`entry` 是已有 OHOS 应用模块;这里只是在其中增加本 App 的原生能力实现。业务代码和 H5 均不得直接调用 channel、ArkTS 或做 OHOS 平台判断。
### `pubspec.yaml` 必须声明 plugin platforms
@@ -197,24 +218,35 @@ pigeon:
- Dart 生成物在根 `analysis_options.yaml` 里排除 lint(`analyzer: exclude: - "**/*.g.dart"`)。
- CI 要有一步"重新生成后 `git diff --exit-code`",防止有人改了 schema 但忘了提交生成物。
## OHOS 后续演进
## OHOS 当前实现策略(`harmony`)
鸿蒙(OpenHarmony)**不在首版范围**,但基线决策是为它留了口子的,这里记录清楚,避免后面接的时候重新走一遍弯路。
OHOS 不是 Android 的另一种 plugin platform。当前 Flutter_OH 工具链没有可直接复用的 Pigeon ArkTS 生成链路;而现有 Pigeon API 在 Dart 侧使用 `BasicMessageChannel`、自定义 codec、类型 tag 和生成的错误/结果 envelope。让 ArkTS 人工复刻该私有 wire protocol,维护成本和接口漂移风险都不值得。
接 OHOS 需要处理三件事:
因此,OHOS 在 `native_scan` 的**内部**新增一条简洁、独立的 `MethodChannel` transport。它接收和返回仅用于该 transport 的基础 Map/List/标量,再映射回既有的 `ScanOptions`、`ScanResult` 与 `NativeScanException`;Android/iOS Pigeon schema、生成物与注册逻辑不因此改变。
1. **SDK 分支不同**:OHOS 用的是 OpenHarmony 社区维护的 Flutter 分支,版本落后于官方 stable 一段时间。这正是 [01-project-structure.md](./01-project-structure.md) 里 SDK 基线刻意停在 **3.44.9** 而不追 3.47.0 的原因——基线跑太前,OHOS 分支跟不上就接不进来。
2. **Pigeon 没有 ArkTS 生成器**:Pigeon 官方只生成 Kotlin/Java、Swift/Objective-C、C++、GObject,**没有 ArkTS/OHOS**。所以 OHOS 侧的 channel 代码只能**手写**,需要人工保证方法名、参数结构与 Pigeon 生成的 Dart 端编解码格式一致——这是一份实打实的额外维护成本,接 OHOS 时要预留出来。
3. **`native_*` 包要加 `ohos:` 平台声明**,并新增 `ohos/` 目录。
ArkTS 按职责拆分,避免把业务实现写进默认入口:
在此之前,`native_*` 的公共 API 类里遇到不支持的平台,一律抛明确的 `UnsupportedPlatformException`,不静默返回空值或占位假数据——静默返回会让"这个平台其实没实现"的问题一直藏到用户手里。
```
app/ohos/entry/src/main/ets/
entryability/EntryAbility.ets # 生命周期、Flutter engine 与 bridge 注册
native_scan/NativeScanChannel.ets # 方法分发、参数/结果序列化、错误映射
native_scan/OhosScanService.ets # 相机/扫码 API 调用
native_scan/ScanPermissionService.ets # 相机权限检查与申请
```
`NativeScanChannel` 必须集中维护 channel 名、方法名、参数、成功返回值与错误码;Dart facade 捕获 `PlatformException` 并继续转为 `NativeScanException`。取消、拒绝权限、能力不可用、超时和未知方法必须分别有明确错误码,不能返回空值或伪造扫描结果。
**延后抽取独立 OHOS plugin。** 只有出现第二个 OHOS App 的复用需求、扫描实现和契约已稳定、Flutter_OH plugin 注册/模板已成熟并经验证,或 SDK 化收益明确超过维护成本时,才评审将 ArkTS 从 `app/ohos/entry` 抽到 `packages/native_scan/ohos`。在此之前,不添加 `ohos:` plugin 声明或额外 `ohos/` 目录。
**SDK 收敛条件。** 当前 Android/iOS 使用 Flutter 3.44.9,OHOS 使用 Flutter_OH 3.41.10-ohos-1.0.0;Flutter_OH 上游文档计划在 **2026 年 9 月**提供 Flutter 3.44.x / Dart 3.12.x 对齐版本。实际 Tag/Commit 发布并验证可用后,可评审统一基线。升级前必须以该候选 SDK 完成依赖解析、Pigeon 与 Riverpod 生成物核验、`flutter build hap --debug -t lib\main_dev.dart` 和真机原生能力回归;不能仅因计划日期或版本号相同就替换工具链。
## 使用规则
- `pigeons/xxx_api.dart` 是**唯一手写**的接口定义文件,Dart 端和两端原生的桩代码全部由 `dart run pigeon --input pigeons/xxx_api.dart` 生成,生成产物不手动修改,改需求就改 schema 重新生成。
- Android/iOS 的 `pigeons/xxx_api.dart` 是**唯一手写**的 Pigeon 接口定义文件;Dart 端及 Kotlin/Swift 桩代码全部由 `dart run pigeon --input pigeons/xxx_api.dart` 生成,生成产物不手动修改。OHOS 不手抄 Pigeon wire protocol,而是维护独立、文档化的 `MethodChannel` 契约。
- Dart 调原生用 `@HostApi()`;原生主动推事件给 Dart(比如扫码结果的持续回调)用 `@FlutterApi()`——不允许为了图省事用 `@HostApi()` 硬凑双向通信。
- **调用方只允许依赖 `native_*` 包 `lib/native_xxx.dart` 导出的公共 API 类**,不允许直接 import `src/generated/` 里的生成代码。调用方包括 `feature_*` 和 `core_webview`(JSBridge)。
- `native_*` 是平台分派和异常收敛的唯一位置;Feature、`core_webview`、H5 与 Dart entrypoint 均不得直接创建 OHOS `MethodChannel` 或 import ArkTS 对应实现。
- 原生侧异常需要在生成的 host API 实现里捕获并转换成 Pigeon schema 里声明的错误类型,Dart 侧统一映射成 [05-networking.md](./05-networking.md) 里同一套 `AppException` 体系,不让原生异常类型(如 `PlatformException`)直接抛到业务代码里。
- 某一端暂未实现的能力,公共 API 类里对应平台分支抛明确的 `UnsupportedPlatformException`,不允许静默返回空值或占位假数据。
+2 -2
View File
@@ -4,7 +4,7 @@ Flutter APP 的分包、分层、技术选型等决策记录,按序号阅读
**这些文档是本仓库代码的约束来源。** 代码和文档不一致时,以文档为准改代码。
首版范围为 **Android / iOS**,鸿蒙 OHOS 不在首版内(但 SDK 基线锁 3.44.9 是为后续 OHOS 适配留窗口,见 01 和 07)。
首版正式交付范围仍为 **Android / iOS**。`harmony` 分支已用 Flutter_OH 完成 OHOS debug HAP 编译验证,但这不是生产可用结论;运行、Dart/ArkTS 桥接、相机扫码和真机验收仍须按 [07](./07-native-integration.md) 的 Gate 完成。
| 文档 | 内容 |
| --- | --- |
@@ -14,7 +14,7 @@ Flutter APP 的分包、分层、技术选型等决策记录,按序号阅读
| [04-routing.md](./04-routing.md) | 路由方案(go_router) |
| [05-networking.md](./05-networking.md) | 网络层设计(dio) |
| [06-local-storage.md](./06-local-storage.md) | 本地存储方案(Drift / secure storage / shared_preferences) |
| [07-native-integration.md](./07-native-integration.md) | 原生能力集成方式(Pigeon) |
| [07-native-integration.md](./07-native-integration.md) | 原生能力集成方式(Android/iOS Pigeon;OHOS 宿主 MethodChannel) |
| [08-build-flavors.md](./08-build-flavors.md) | 多环境构建(dev/uat/prod flavor) |
| [09-testing.md](./09-testing.md) | 测试策略(单元/Widget/集成测试) |
| [10-webview-h5.md](./10-webview-h5.md) | Embedded H5 容器与 JSBridge(PRD §7 核心链路) |