Flutter 项目接入 HarmonyOS 的完整工程结构解析

适合谁看

  • 正在把 Flutter 项目接到 HarmonyOS 的开发者

  • 已经看到 app/ohos/,但还没有整体结构感的人

  • 想先建立工程地图,再逐个理解具体文件的人

问题背景

Flutter 项目接入鸿蒙以后,仓库不再只是:

  • lib/

  • android/

  • ios/

而是会多出一整套 app/ohos/ 结构。很多人第一次看到它时,容易出现两种误判:

  • 误以为它只是 Flutter 自动生成出来的附属目录

  • 误以为只要会改 module.json5 就算理解了鸿蒙接入

这两种看法都不够。

因为真正决定后面能不能顺利接语音、TTS、Intent、卡片、防窥这些能力的,是你有没有先把整个工程结构理解成一个分层系统。

项目中的真实场景

食界探味当前的项目结构很适合讲这件事,因为它不是只保留一个最简壳工程,而是已经把鸿蒙项目里最典型的几层都用上了:

  • Flutter 业务代码在 app/lib/

  • HarmonyOS 壳工程在 app/ohos/

  • 主入口在 app/ohos/entry/src/main/ets/entryability/EntryAbility.ets

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

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

  • 模块声明在 app/ohos/entry/src/main/module.json5

换句话说,这个项目里已经能看到一条比较完整的接入链路。

核心实现

如果把 Flutter 项目接入 HarmonyOS 之后的结构压缩成一个最小模型,我更建议先这样理解:

复制代码
Flutter 业务层
    ↓
Flutter 平台边界层
    ↓
HarmonyOS 壳工程
    ↓
系统入口 / 原生插件 / 卡片能力

这里最重要的一点是:

app/ohos/ 不是来替代 Flutter 的,而是来承接 Flutter 无法直接承担的系统现实。

如果你是第一次真正读一个已经接好鸿蒙壳工程的 Flutter 项目,我建议先别急着逐个文件死读。

更稳的顺序通常是:

  1. 先看整体分层

  2. 再看 app/ohos/ 顶层

  3. 再看 entry 模块

  4. 最后才看具体的 EntryAbilityplugins/formability/

这样你后面读具体文件时,脑子里已经有一张"它在整条链上负责什么"的地图。

第一层:Flutter 业务层继续留在 app/lib/

接入 HarmonyOS 之后,Flutter 主体并没有消失。

像食界探味里真正面向用户的内容,依然主要集中在:

  • app/lib/features/

  • app/lib/data/

  • app/lib/core/

它们负责的是:

  • 页面 UI

  • 路由

  • 状态管理

  • 数据组织

  • 业务流程

这意味着接入鸿蒙不等于"把项目改写成 ArkTS 项目",而是让 Flutter 业务层和鸿蒙系统层协同。

第二层:平台边界继续收在 app/lib/core/platform/

很多人会以为接了鸿蒙之后,所有和平台相关的东西都应该直接写进 app/ohos/

但食界探味当前的结构恰好说明,Flutter 和 ArkTS 之间最好还有一层专门的边界层:

  • app/lib/core/platform/speech_recognition_channel.dart

  • app/lib/core/platform/text_to_speech_channel.dart

  • app/lib/core/platform/intent_navigation_channel.dart

  • app/lib/core/platform/anti_peep_protection_channel.dart

这一层的价值是:

  • 对 Flutter 页面隐藏原生细节

  • 对 ArkTS 插件统一调用协议

  • 让页面层不直接碰 MethodChannel 的底层细节

所以从工程结构看,HarmonyOS 接入不是"Flutter 一层 + 原生一层",而是至少三层:

  • Flutter 业务层

  • Flutter 平台边界层

  • HarmonyOS 原生层

第三层:app/ohos/ 是正式的鸿蒙壳工程

真正的鸿蒙接入主体就在 app/ohos/

这个目录里最值得先建立的认知不是"文件很多",而是"它本身就是一个正式平台层"。

在食界探味里,可以先抓住这几个位置:

  • app/ohos/build-profile.json5

  • app/ohos/oh-package.json5

  • app/ohos/entry/

其中:

  • build-profile.json5 更接近构建和签名层

  • oh-package.json5 更接近鸿蒙依赖层

  • entry/ 更接近应用模块本体

如果再结合当前工程里的真实内容看,会更容易建立感觉:

  • app/ohos/build-profile.json5 已经定义了 debug / profile / release

  • app/ohos/oh-package.json5 是鸿蒙工程级别的包与依赖入口

  • app/ohos/entry/ 下面再继续分模块、源码、构建目标

也就是说,app/ohos/ 不是一个"单文件配置区",而是一个正式平台工程根目录。

第三层半:先别急着进源码,先把"顶层三件套"分清

很多人第一次进鸿蒙工程时,最容易把这三类文件混在一起:

  • build-profile.json5

  • oh-package.json5

  • module.json5

但它们解决的问题其实不同:

  • build-profile.json5 更像"怎么构建、怎么签名、产物怎么出"

  • oh-package.json5 更像"这个鸿蒙工程依赖什么包"

  • module.json5 更像"这个模块是什么、入口是谁、权限和扩展能力有哪些"

当前项目里,最值得先建立的习惯就是:

  • 构建问题优先看 build-profile.json5

  • 依赖问题优先看 oh-package.json5

  • 入口、权限、扩展能力问题优先看 module.json5

一旦这三个职责混了,后面排查问题会越来越费劲。

第四层:entry 模块承接真正的鸿蒙应用入口

app/ohos/entry/ 是这个工程里最值得优先理解的地方。

因为从这里开始,你看到的已经不是抽象的"鸿蒙支持",而是具体的应用模块结构。

其中最关键的是:

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

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

module.json5 负责声明这个模块是什么、入口是什么、权限是什么、有哪些扩展能力。

EntryAbility.ets 负责接住真正的应用启动和系统参数。

这两者配合起来,才构成了 Flutter 应用在鸿蒙上的正式落点。

结合当前项目里的真实内容,可以把 module.json5 先粗读成四块:

  • mainElement: "EntryAbility":说明应用主入口是谁

  • abilities:说明主 Ability 怎么声明

  • extensionAbilities:说明除了主入口之外,还声明了哪些扩展能力

  • requestPermissions:说明这个模块需要哪些系统权限

而这份工程里你已经能看到两个非常具体的鸿蒙特征:

  • DailyRecommendFormAbility 已经作为 extensionAbilities 声明进来了

  • MICROPHONEDLP_GET_HIDE_STATUS 这些权限已经进了 requestPermissions

这两点很重要,因为它说明:

  • 这不是"只会启动 Flutter 页面"的最简工程

  • 而是已经开始正式承接语音、防窥、卡片这些鸿蒙能力

第五层:ArkTS 源码并不只有一个"主入口文件"

很多人最初读鸿蒙工程时,会以为:

  • 有一个入口

  • 有一个页面

  • 然后 Flutter 自己跑

但食界探味现在的结构明显更完整。

app/ohos/entry/src/main/ets/ 下面至少已经分出几类职责不同的目录:

  • entryability/:应用主入口和系统入口承接

  • plugins/:系统能力插件实现

  • formability/:卡片能力

  • pages/:Flutter 容器页面

这四类目录本身就说明了一个事实:

Flutter 项目接入 HarmonyOS 后,不是只有一个"启动壳",而是一整套系统承接层。

如果你是第一次看 ets/,我更建议先把它理解成四个问题:

  • 应用怎么启动:看 entryability/

  • 系统能力怎么桥接:看 plugins/

  • 卡片怎么承接:看 formability/

  • Flutter 页面怎么挂到鸿蒙容器里:看 pages/

用这四个问题去读目录,会比死记目录名更有效。

第六层:页面壳、插件壳、卡片壳分别承担不同任务

拿食界探味现有实现举例,会更容易建立结构感。

app/ohos/entry/src/main/ets/pages/Index.ets 里,核心是 FlutterPage({ viewId: this.viewId })

它说明这一层主要负责把 Flutter 页面真正挂到鸿蒙页面容器里。

app/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets 负责注册 Flutter 插件生态里的 Ohos 插件,比如:

  • url_launcher_ohos

  • shared_preferences_ohos

  • sqflite

  • path_provider_ohos

EntryAbility.ets 里又额外手动注册了食界探味自己封装的插件:

  • SpeechRecognitionPlugin

  • TextToSpeechPlugin

  • IntentNavigationPlugin

  • AntiPeepProtectionPlugin

这说明项目里的鸿蒙接入不是单层结构,而是:

  • 一层承接 Flutter 引擎

  • 一层承接官方或生态插件

  • 一层承接项目自定义原生能力

如果再往前推进一步,其实还可以把 EntryAbility.ets 里的职责拆得更具体:

  • configureFlutterEngine:注册 Flutter 生态插件和项目自定义插件

  • onCreate:承接冷启动参数

  • onNewWant:承接运行中的新入口请求

  • onWindowStageCreate:初始化窗口环境

这就是为什么我前面一直说,鸿蒙壳工程不是"让 Flutter 能跑就行"。

到了这个层级,它已经在正式管理:

  • Flutter 引擎

  • 系统入口

  • 原生能力注册

  • 窗口环境

第七层:系统入口和卡片能力也是接入结构的一部分

如果只把鸿蒙接入理解成"能跑起来",那很容易忽略后面这两层:

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

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

前者说明系统意图入口已经接进来了。

后者说明卡片能力已经接进来了。

这意味着在食界探味里,HarmonyOS 接入不是"应用能启动"这么简单,而是已经延伸到:

  • 搜索或系统入口直达

  • 卡片触达

  • 系统能力插件化

这也是为什么理解工程结构必须先从整体入手,而不是只盯着一个配置文件。

到这里其实就能得到一个很重要的判断:

一个 Flutter 项目是否真的"接入了 HarmonyOS",不是看它有没有 ohos/ 目录,而是看它有没有把入口、插件、权限、卡片和页面容器都接成一条完整链。

当前项目已经很接近这条完整链了,所以特别适合拿来讲"完整工程结构",而不是只讲某一个能力接入。

第八层:第一次真正读这套工程时,建议按这个顺序

如果你打算把这篇文章写成能直接发的教程,那我建议一定把"阅读顺序"明确写出来。

对第一次接触鸿蒙壳工程的人来说,这比解释一堆名词更有用。

建议顺序可以直接照当前项目来:

  1. 先看 app/ohos/ 顶层,建立"这是正式平台工程"的意识

  2. 再看 app/ohos/build-profile.json5app/ohos/oh-package.json5

  3. 再进 app/ohos/entry/,把它当成真正的应用模块去看

  4. 然后先读 app/ohos/entry/src/main/module.json5

  5. 再读 app/ohos/entry/src/main/ets/entryability/EntryAbility.ets

  6. 最后才读 plugins/formability/pages/

为什么这个顺序更稳?

  • 因为它先帮你建立"系统结构感"

  • 再帮你建立"模块声明感"

  • 最后才进具体实现

很多人之所以第一次看鸿蒙工程会慌,不是因为文件太多,而是因为顺序反了。

关键代码位置

  • app/lib/

  • app/lib/core/platform/

  • app/ohos/build-profile.json5

  • app/ohos/oh-package.json5

  • app/ohos/entry/build-profile.json5

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

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

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

  • app/ohos/entry/src/main/ets/pages/Index.ets

鸿蒙侧实现

从鸿蒙侧看,这套接入结构至少分成三类职责:

  • EntryAbility 承接应用主入口和系统参数

  • plugins/ 承接语音、TTS、Intent、防窥等原生能力

  • formability/ 承接卡片能力

module.json5 则像这一切的模块说明书,告诉系统:

  • 入口是谁

  • 扩展能力有哪些

  • 权限需要什么

如果再结合当前项目的真实文件,你可以把鸿蒙侧接入理解成一条实际运行链:

  1. build-profile.json5 决定构建目标和签名产物

  2. module.json5 决定模块入口、权限和扩展能力

  3. EntryAbility.ets 决定 Flutter 引擎、插件注册和启动参数承接

  4. pages/Index.ets 决定 Flutter 页面如何挂进鸿蒙容器

  5. plugins/ 决定语音、TTS、Intent、防窥等原生能力如何桥接

  6. formability/ 决定卡片如何进入系统桌面触达链

这就是 HarmonyOS 壳工程真正有价值的地方:

它把"启动""能力""入口""卡片"全都接成了一个正式系统层。

Flutter 侧实现

从 Flutter 侧看,接入 HarmonyOS 之后最重要的不是"改很多 Dart 代码",而是把职责收清楚:

  • app/lib/ 继续负责页面、状态和业务

  • app/lib/core/platform/ 负责和 ArkTS 之间的边界

  • Flutter 页面不直接碰 AbilityWantFormExtensionAbility 这些系统概念

这也是这套工程结构能长期维护的关键。

也就是说,Flutter 侧最稳的姿势并不是:

  • 一看到鸿蒙能力就去页面里直接桥接原生

而是:

  1. 页面和业务状态继续留在 app/lib/

  2. Flutter 和 ArkTS 之间的边界继续收在 app/lib/core/platform/

  3. app/ohos/ 去承接真正的系统现实

当前项目里像:

  • speech_recognition_channel.dart

  • text_to_speech_channel.dart

  • intent_navigation_channel.dart

  • anti_peep_protection_channel.dart

就已经把这层边界收得比较清楚了。

这也是为什么我会说,这篇工程结构文必须把 Flutter 侧和鸿蒙侧一起讲,而不能只盯着 app/ohos/

常见坑

  • app/ohos/ 当成纯自动生成目录,从而不愿意读它

  • 只盯着 module.json5,不先建立整体结构感

  • 把鸿蒙接入理解成"能跑起来就行",忽略了插件、入口和卡片层

  • 以为 Flutter 接入鸿蒙后,业务层应该大量迁到 ArkTS

  • 第一次读工程时直接扎进 plugins/,结果越看越乱

  • 没分清 build-profile.json5oh-package.json5module.json5 三者职责

  • 看到 EntryAbility.ets 只当作启动文件,没有意识到它还在管理引擎、插件和系统入口

可复用模板

复制代码
Flutter 项目
├── lib/                         # 页面、状态、业务
├── android/                     # Android 壳工程
├── ios/                         # iOS 壳工程
└── ohos/                        # HarmonyOS 壳工程
    ├── build-profile.json5      # 构建与签名
    ├── oh-package.json5         # 鸿蒙依赖
    └── entry/
        └── src/main/
            ├── module.json5     # 模块声明
            └── ets/
                ├── entryability/
                ├── plugins/
                ├── formability/
                └── pages/

建议阅读顺序
1. 先看 app/ohos 的大结构
2. 再看 build-profile.json5 / oh-package.json5
3. 再看 entry/src/main/module.json5
4. 再看 EntryAbility
5. 最后看 plugins / formability / pages

本篇总结

Flutter 项目接入 HarmonyOS 后,真正新增的不是一个孤立目录,而是一套正式的系统承接层。

在食界探味里,这套结构已经很清楚地分成了:

  • Flutter 业务层

  • Flutter 平台边界层

  • HarmonyOS 壳工程层

  • 系统入口、插件和卡片层

只要先把这张工程地图建立起来,后面再读 app/ohos/ 里的单个文件,就不会总觉得它们是零散配置了。

对第一次做鸿蒙 Flutter 接入的人来说,这比死记某个配置项更重要,因为它决定了你后面接插件、接 Intents Kit、接卡片时会不会一直迷路。

相关推荐
●VON1 小时前
AtomGit Flutter鸿蒙客户端:通知系统
flutter·华为·跨平台·harmonyos·鸿蒙
小雨下雨的雨7 小时前
井字棋AI机器人实现详解 - Minimax算法实战-鸿蒙PC Electron框架完成
前端·人工智能·算法·华为·electron·鸿蒙
不爱吃糖的程序媛12 小时前
鸿蒙服务卡片实战:为新华字典应用添加桌面快捷查询卡片
华为·harmonyos
zeqinjie14 小时前
Flutter 折叠屏 iPad / 宽屏适配实践
android·前端·flutter
Davina_yu14 小时前
弹窗交互:AlertDialog与CustomDialog的创建与关闭(11)
harmonyos·鸿蒙·鸿蒙系统
90后的晨仔14 小时前
HarmonyOS 锁屏音频播放完整实践指南
harmonyos
90后的晨仔14 小时前
鸿蒙应用动态桌面图标功能实现完全指南
harmonyos
nashane15 小时前
HarmonyOS 6学习:JsCrash“闪退”法医指南——从FaultLog堆栈还原崩溃现场的终极手册
学习·华为·harmonyos