适合谁看

  • 正在做多端共存 Flutter 工程的人

  • 想把 HarmonyOS 加进现有 Flutter 项目的人

  • 担心平台目录越来越乱的人

问题背景

很多人做 Flutter 多端时,最初的默认想法通常是:

  • 业务层共用

  • 平台层尽量少看

这个思路在 Android + iOS 双端阶段通常还能撑住。
但 HarmonyOS 加进来以后,复杂度会变得更立体一些:

  • 入口模型不同

  • 系统能力层不同

  • 构建与签名链路不同

  • 卡片和意图直达这类系统触达也会进来

这时如果还沿用“先都塞进共享层,平台差异以后再说”的思路,项目很容易越做越乱。

真正的问题不是三端能不能共存,而是:

共享什么、隔离什么、谁负责承接平台现实。

项目中的真实场景

食界探味当前就是一个很典型的三端共存结构:

  • app/android/

  • app/ios/

  • app/ohos/

  • app/lib/

其中:

  • app/lib/ 继续承接 Flutter 主体业务

  • app/ohos/ 独立承接 HarmonyOS 壳工程

  • app/lib/core/platform/ 承接 Flutter 与平台层的边界

如果再往细里看,会更清楚:

  • Flutter 侧的平台边界文件在 app/lib/core/platform/

  • HarmonyOS 侧原生插件在 app/ohos/entry/src/main/ets/plugins/

  • HarmonyOS 侧入口承接在 app/ohos/entry/src/main/ets/entryability/

  • HarmonyOS 侧卡片能力在 app/ohos/entry/src/main/ets/formability/

这恰好说明,三端共存最重要的不是“目录都留着”,而是“共享和隔离的边界有没有先收清”。

核心实现

先说一个最实用的判断:

多端共存的关键从来不是“所有东西都共享”,而是“共享业务语义,隔离平台现实”。

只要先记住这一句,很多结构选择都会清楚很多。

一、应该优先共享什么

在食界探味这种 Flutter 主体项目里,优先共享的部分通常包括:

  • 页面

  • 路由

  • 状态管理

  • 数据模型

  • 仓储层

  • 业务流程

这些内容主要集中在:

  • app/lib/features/

  • app/lib/data/

  • app/lib/core/

它们的共同点是:

  • 更接近产品体验

  • 更接近跨平台业务

  • 不依赖某一个平台独占的系统能力

所以这些东西继续留在 Flutter 共享层,是合理而且高性价比的。

二、必须按平台隔离什么

一旦进入下面这些内容,就应该主动接受“它们不该强行共享”:

  • 原生插件实现

  • 权限流程

  • 系统入口模型

  • 卡片与桌面触达

  • 平台构建和签名配置

在食界探味里,HarmonyOS 这部分复杂度就明显集中在:

  • app/ohos/

  • app/ohos/build-profile.json5

  • app/ohos/entry/src/main/module.json5

  • app/ohos/entry/src/main/ets/plugins/

  • app/ohos/entry/src/main/ets/entryability/

  • app/ohos/entry/src/main/ets/formability/

这说明 HarmonyOS 加进来以后,平台隔离不只是“多一个目录”,而是多了一整层系统承接结构。

三、为什么 app/lib/core/platform/ 在三端共存里特别关键

如果只有 Android 和 iOS,有些团队会把平台差异直接零散写进页面层。
但三端共存以后,这种方式会很快变得不可控。

食界探味当前的结构给了一个更稳的方向:

  • 平台能力先收进 app/lib/core/platform/

  • Flutter 页面层只调语义化方法

  • 各平台壳工程再各自实现自己的那一段系统现实

当前已经能看到的边界文件包括:

  • anti_peep_protection_channel.dart

  • intent_navigation_channel.dart

  • speech_recognition_channel.dart

  • text_to_speech_channel.dart

这样做的好处是:

  • 页面层不直接碰平台差异

  • HarmonyOS 的新复杂度不会直接冲进业务层

  • 后面 Android、iOS、HarmonyOS 可以各自扩展实现

四、HarmonyOS 加进来后,项目复杂度为什么会明显上一个台阶

这不是因为 HarmonyOS “更难”,而是因为它带来的差异更立体。

以食界探味现在的鸿蒙壳工程为例,至少已经能看到这些新增复杂度:

  • EntryAbility 主入口

  • InsightIntentExecutorImpl 意图入口

  • DailyRecommendFormAbility 卡片入口

  • 语音、TTS、Intent、防窥这些原生插件

  • module.json5build-profile.json5 这类鸿蒙配置层

也就是说,HarmonyOS 不是只多出一个“运行平台”,而是多出了一层更强的系统入口和系统能力语境。
这也是为什么三端共存时,HarmonyOS 一进来就更需要主动管理平台边界。

五、三端共存时,新增一个鸿蒙能力应该改哪几层

这是实际开发里最容易把工程做乱的地方。

如果现在要在食界探味里新增一个 HarmonyOS 独占能力,比如新的系统级入口或新的 Kit 能力,我更建议按下面这个顺序落:

第一步:先定义 Flutter 侧语义接口

先在:

  • app/lib/core/platform/

里定义清楚:

  • 这个能力对 Flutter 页面来说叫什么

  • 它返回的是一次性结果还是持续事件

  • 失败时页面应该拿到什么语义

第二步:再决定 HarmonyOS 壳层谁来承接

如果它是:

  • 一次性能力调用,通常落在 plugins/

  • 系统入口能力,通常会牵涉 entryability/

  • 卡片或桌面触达能力,通常会牵涉 formability/

这一步的意义是,不要让所有鸿蒙能力都无差别堆进同一个原生文件。

第三步:最后再看 Android、iOS 是否需要跟进

三端共存不等于三端必须同时做同一件事。
有些能力只在鸿蒙上存在,那就应该老老实实只在鸿蒙层实现,并在 Flutter 边界层做好:

  • 能力探测

  • 平台判断

  • 降级策略

六、最稳的多端工程思路是什么

如果压缩成一个最小实践,可以先这样做:

共享层
  • app/lib/

这里放:

  • 页面

  • 路由

  • 状态

  • 数据模型

  • 仓储与业务流程

平台边界层
  • app/lib/core/platform/

这里放:

  • 平台语义化调用入口

  • 结果和事件收口

  • 平台异常兜底

平台实现层
  • app/android/

  • app/ios/

  • app/ohos/

这里放:

  • 构建配置

  • 权限与系统入口

  • 原生插件和平台特定实现

只要先按这三层收,后面多端共存通常都会稳定很多。

七、哪些迹象说明你的三端结构开始失控了

如果项目里开始出现下面这些信号,就说明平台边界可能已经在变形:

  • Flutter 页面里到处是平台判断分支

  • 一个新能力要同时改页面、业务、路由和多端原生代码,却没有明确边界

  • HarmonyOS 的入口和插件逻辑开始直接侵入共享业务层

  • Android、iOS、HarmonyOS 的实现差异没有收口,而是散落在很多 Dart 页面里

这类问题早期看起来只是“有点乱”,后面会直接影响:

  • 维护成本

  • 新能力接入速度

  • 教程可读性

  • 回归排查效率

关键代码位置

  • app/lib/

  • app/lib/core/platform/

  • app/android/

  • app/ios/

  • app/ohos/

  • app/ohos/entry/src/main/ets/plugins/

  • app/ohos/entry/src/main/ets/entryability/

  • app/ohos/entry/src/main/ets/formability/

鸿蒙侧实现

从鸿蒙侧看,新增复杂度主要不在 Flutter 页面层,而在壳工程和系统能力层:

  • EntryAbility

  • plugins/

  • formability/

  • module.json5

  • build-profile.json5

所以 HarmonyOS 不应该被看成“又一个外壳”,而应该被看成“多端体系里独立的一层系统入口实现”。

Flutter 侧实现

从 Flutter 侧看,最重要的目标不是把所有平台差异隐藏到看不见,而是把它们控制在页面层外面。

食界探味现在的做法更接近:

  • Flutter 承接共享业务

  • 平台边界层承接平台语义

  • 各平台壳工程承接系统现实

这比“平台差异直接混进页面层”要稳得多。

常见坑

  • 为了共用而硬把平台差异塞进 Dart 页面层

  • HarmonyOS 接入后没有重新划清平台边界

  • 看到 Flutter 可跨平台,就误以为平台入口和权限流程也应该完全共享

  • 三端共存时没有独立平台边界层,最后页面到处都是条件分支

  • 新增一个鸿蒙能力时,不先决定它落在 plugins/entryability/ 还是 formability/

可复用模板

共享层:app/lib/
边界层:app/lib/core/platform/
平台层:android/ ios/ ohos/
共享的是
- 业务语义
- 页面体验
- 数据组织

隔离的是
- 系统入口
- 权限流程
- 原生能力
- 构建与签名

本篇总结

一个 Flutter 项目同时保留 Android、iOS、HarmonyOS 支持时,最关键的不是“目录都还在”,而是共享和隔离的边界是否足够清楚。
食界探味当前的结构说明,真正稳的做法不是强行统一所有实现,而是:

  • 共享业务层

  • 独立平台层

  • 中间再加一层稳定的平台边界层

HarmonyOS 一旦进来,这件事反而更重要,而不是更可忽略。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐