鸿蒙原生生态起来之后,最焦虑的其实不是原生开发者,反而是我们这批Flutter开发者。原生的ArkTS要学,已有的Flutter应用又不想丢,到底怎么选?我自己的做法是:鸿蒙 + Flutter 混合开发,用 Flutter 承载业务界面,把鸿蒙的图库、支付、分享这些原生能力通过 Channel 暴露给上层调用。这篇文章把我实际落地的项目经验拆开了讲,从工程搭建、原生能力调用、数据层设计到多端适配、踩坑实录,一条龙捋清楚。既适合准备把现有 Flutter 应用迁到鸿蒙上的团队参考,也适合正在准备鸿蒙开发面试、想搞明白混合架构到底怎么玩的朋友。
1. 项目整体设计与架构思路
1.1 为什么选混合开发而不是“二选一”
先说一个很现实的问题:Flutter 能不能直接跑在鸿蒙上?答案是可以的,但不是官方 Flutter SDK 开箱即用,而是通过 OpenHarmony 生态适配的 Flutter 引擎。目前社区里有多个维护中的 fork,比如 flutter_flutter 的 ohos 分支,配合 DevEco Studio 里的鸿蒙工程模板,基本能做到“一套 Dart 代码跑鸿蒙 + Android”,但完全指望这套方案代替原生开发不现实。
混合开发的定位在于“各取所长”:
- Flutter 负责 UI 与业务逻辑:跨端复用率高,团队里已有的 Flutter 基建和组件库可以继续用。
- 鸿蒙原生负责系统能力:图库、IAP 支付、扫码、系统分享、NFC、蓝牙等能力在 Flutter 侧没有现成插件,或者插件不维护了,直接用原生实现最稳。
拿我自己做的一个工具类 App 举例:界面层 90% 以上是 Flutter 写的,但需要拉起鸿蒙 IAP 支付、读取系统相册、唤起系统分享面板时,全部走原生侧。如果一开始就纯 Flutter 硬上,有些原生能力真的调不通;如果纯原生开发,等于把之前的跨端积累全丢了。混合开发不是逃避原生,而是把原生能力封装成“可复用网关”,让 Flutter 侧只关心业务。
1.2 架构分层:Channel 是混合开发的中枢神经
混合开发的第一步是定架构。我采用的是一种比较经典的分层结构:
- UI 层(Flutter):页面、组件、状态管理,全部在 Flutter 工程里。
- 桥接层(MethodChannel / EventChannel):负责 Dart 与鸿蒙原生侧的方法调用和事件通知。
- 原生能力层(ArkTS):实现鸿蒙系统 API 的调用,包括 IAP、相册、分享、数据存储等。
- 数据层:Flutter 内嵌数据库负责本地缓存,原生侧通过 ContentProvider 或 DataShare 与系统数据交互。
这套分层的核心逻辑很简单:Flutter 不知道鸿蒙 API 长什么样,鸿蒙原生也不知道 Flutter 的 Widget 怎么渲染,中间全靠 Channel 传字符串方法和 JSON 参数。好处是职责清晰,替换成本低;坏处是 Channel 通信有序列化开销,不适合高频大数据量场景。所以我在设计时约定:超过 2MB 的数据(比如图片、视频路径)不走 Channel 传 base64,而是传文件路径或 URI,由原生侧直接处理文件。
1.3 混合开发 vs 纯原生 vs 纯 Flutter:一张表看明白
| 维度 | 纯 ArkTS 原生 | 纯 Flutter | 鸿蒙 + Flutter 混合 |
|---|---|---|---|
| 跨端复用能力 | 低,基本只能鸿蒙用 | 高,Android/iOS/Web 通用 | 中高,Flutter 部分可跨端 |
| 系统能力覆盖 | 最全,最新 API 都能用 | 依赖三方插件,鸿蒙适配滞后 | 原生缺失能力可自行桥接 |
| 团队学习成本 | 需重新学 ArkTS/ArkUI | 已有 Flutter 基础即可 | 需一个会 ArkTS 的成员 |
| 工程复杂度 | 低 | 低 | 中高,需要维护双工程 |
| 适合场景 | 鸿蒙专属 App、强系统联动 | 纯跨端应用,系统能力需求少 | 现有 Flutter 应用迁移/系统能力多 |
我对团队的建议是:如果你是全新项目、且主要目标设备就是鸿蒙手机,那直接纯原生 ArkTS 开发没有毛病;如果你有成熟的 Flutter 代码库要迁移,或者对多端复用有要求,混合开发是成本收益比最合适的方案。如果团队一个 ArkTS 的人都没有,那我不建议一上来就混合开发,因为原生侧出了问题你连排查都无从下手。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境搭建与工程结构设计
2.1 鸿蒙 Flutter 开发环境准备
混合开发的环境配置比普通 Flutter 项目繁琐,主要是因为除了 Flutter SDK,还要装 DevEco Studio、鸿蒙 SDK,而且 Flutter SDK 要用支持 OpenHarmony 的分支版本。
我实测下来的步骤大致是:
- 安装 DevEco Studio,这个直接去华为开发者官网下载即可,安装时会自动带上鸿蒙 SDK。
- 获取支持鸿蒙的 Flutter SDK。比较简单的做法是直接用
flutter_flutter项目的 ohos 分支,或者用社区维护的镜像仓库。我个人的习惯是 git clone 后切换到对应分支,然后把 SDK 路径配到环境变量里。 - 安装依赖命令行工具,包括
ohpm(鸿蒙包管理器)和 DevEco 自带的一些工具链。 - 运行
flutter doctor -v,确认 Flutter、DevEco、鸿蒙 SDK 的路径都识别到了。 - 创建工程之后,用 DevEco Studio 打开,配置签名证书,再跑模拟器或真机。
这里有个特别容易踩的坑:PATH 环境变量配了但新终端不生效。很多人在 macOS 上改完 ~/.zshrc 就直接在当前终端敲命令,结果提示找不到 flutter。解决方案是先跑一下 source ~/.zshrc 或者新开一个终端窗口。Windows 上用 VS Code 也类似,改完环境变量必须重启终端进程才生效,不然 flutter 命令会一直指向旧版本。
2.2 创建原生 + Flutter 双端工程
混合开发的工程载体选择很重要,因为鸿蒙侧有独立的工程结构(Ability、Module、资源文件),Flutter 侧又是 Dart 工程。我推荐“原生为主、Flutter 为模块”的结构:
- 用 DevEco Studio 创建一个原生工程。
- 在原生工程的某个 Module 里放置 Flutter 模块源码。
- 通过项目配置(如 build-profile.json)把 Flutter 模块挂载到 hap 打包流程中。
实际工程目录大致是这样:
code复制MyApp/
├── AppScope/ # 应用全局配置,权限声明
├── entry/ # 主 Module,包含 MainAbility
│ ├── src/main/ets/ # ArkTS 源码,写原生桥接层
│ ├── src/main/resources/ # 资源文件
│ └── oh-package.json5 # oho
