适合谁看

  • 已经有 Flutter 经验,正在评估是否投入鸿蒙开发的人

  • 手里已经有 Flutter 项目,想迁移到 HarmonyOS 的人

  • 想做 HarmonyOS 比赛、迁移方案或技术连载,但不想从零重写整套 ArkTS 的人

问题背景

很多人第一次接触鸿蒙开发时,脑子里都会先冒出一个判断:

既然是 HarmonyOS,那是不是应该直接全量 ArkTS?

这个判断对“从零做一个纯鸿蒙原生项目”的团队来说并没有问题。但如果你已经有 Flutter 技术栈、已有业务代码、已有设计资源、已有内容体系,那么真正的问题其实不是“哪种技术更正统”,而是:

哪条路线能更快做出完整产品,同时又保留已有积累?

食界探味 这个项目给我的答案很明确:

  • 业务主体继续用 Flutter

  • 只有明确依赖 HarmonyOS 系统能力的部分,才下沉到 ArkTS

这不是“妥协方案”,而是一种很务实的工程策略。

先说结论:为什么这个项目没有一上来就全量 ArkTS

一句话概括:

因为这个项目当前要解决的重点,不是“是否全原生”,而是“业务层、内容层、AI 交互和鸿蒙能力如何组合成一个可维护的工程结构”。

食界探味的定位并不是一个底层技术展示工程,而是一个真实产品:

以食材为入口,探索全球不同吃法的美食探索 App。

换句话说,这个项目一开始要解决的就不是“如何单独演示某个鸿蒙 API”,而是更完整的产品问题:

  • 内容探索

  • 页面交互

  • AI 助手

  • 多平台支持

  • HarmonyOS 系统能力接入

在这个前提下,我更关心的是:

  1. 业务层能不能尽快稳定

  2. 页面和交互能不能高效迭代

  3. 鸿蒙差异化能力能不能按需接入

  4. 项目能不能持续写成教程、方案和比赛材料

如果用这四个标准来评估,当前这类项目更容易落到“Flutter 承担业务主体、ArkTS 承担系统能力”的结构。

项目中的真实场景

这个项目当前的工程形态,非常典型地体现了这种思路。

1. Flutter 仍然是主业务层

Flutter 相关代码主要在:

  • app/lib/

  • app/lib/features/

  • app/lib/core/

  • app/lib/data/

这里承担了绝大部分真正的产品复杂度:

  • 页面结构

  • 路由组织

  • 状态管理

  • 数据模型

  • 网络请求

  • AI 交互

2. 鸿蒙工程作为平台壳存在

HarmonyOS 工程集中在:

  • app/ohos/

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

它主要负责:

  • HarmonyOS 壳工程与配置

  • EntryAbility / FormAbility

  • ArkTS 插件实现

  • 系统能力调用

3. 平台桥接单独收口

Flutter 到鸿蒙原生的桥接,被非常明确地收在:

  • app/lib/core/platform/

目前已经能看到几个典型桥接:

  • speech_recognition_channel.dart

  • text_to_speech_channel.dart

  • intent_navigation_channel.dart

  • anti_peep_protection_channel.dart

这说明这个项目一开始就没打算让 ArkTS 侵入所有业务层,而是有意识地把平台能力收敛成“边界清晰的能力出口”。

为什么食界探味当前没有直接全量使用 ArkTS

下面我分 5 个维度来讲。

1. 这个项目的主要复杂度,在业务层,不在原生层

先看 app/pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  flutter_riverpod: ^2.6.1
  go_router: ^15.1.2
  dio: ^5.8.0+1
  shared_preferences: ^2.5.3
  cached_network_image: ^3.4.1
  flutter_cache_manager: ^3.4.1
  flame: ^1.35.1
  flutter_svg: ^2.2.4

这几个依赖已经很能说明问题:

  • flutter_riverpod 说明项目有明确的状态管理设计

  • go_router 说明路由不是单页 Demo,而是有较完整导航体系

  • dio 说明存在真实接口交互

  • shared_preferencescached_network_imageflutter_cache_manager 说明有本地状态与资源缓存

也就是说,食界探味 的主要工作量其实在:

  • 业务建模

  • 交互组织

  • 内容展示

  • AI 与业务流程编排

这些部分如果统一改成 ArkTS,迁移成本会明显增加,迭代节奏也会受到影响。

2. Flutter 更适合先承担产品验证阶段的业务层

食界探味 不是一个“只展示系统能力”的项目,它有明确产品目标:

  • 首页探索

  • 食材页

  • 吃法详情页

  • 收藏功能

  • AI 探味助手

从教程和比赛角度看,我更需要的是:

  • 先把完整体验搭出来

  • 再把鸿蒙特色能力接进去

如果一上来就全量 ArkTS,我会先花大量时间在:

  • 重建页面结构

  • 重建状态体系

  • 重建路由组织

  • 重建已有组件

  • 重建调试习惯

这会让项目过早进入“工程重构期”,而不是“产品验证期”。

而 Flutter 的优势就在于:

  • UI 迭代快

  • 组件复用高

  • 跨平台资产保留更完整

  • 文章传播范围更大

3. 鸿蒙的真正增量价值,可以通过按需桥接获得

很多人会误以为,不全量 ArkTS 就享受不到鸿蒙价值。其实不是。

食界探味 当前已经证明,HarmonyOS 的关键差异化能力,完全可以通过“按需下沉”的方式接入。

例子一:语音识别

Flutter 侧的接口非常薄:

文件:app/lib/core/platform/speech_recognition_channel.dart

class SpeechRecognitionChannel {
  static const _channel = MethodChannel('com.foodvoyage.speech_recognition');

  static Future<String> startListening({String language = 'zh-CN'}) async {
    final result = await _channel.invokeMethod<String>(
      'startListening',
      {'language': language},
    );
    return result ?? '';
  }
}

而真正依赖鸿蒙系统能力的部分,被收在 ArkTS 插件里:

文件:app/ohos/entry/src/main/ets/plugins/SpeechRecognitionPlugin.ets

这里做了三件 Flutter 很难直接做好的事:

  • 申请 ohos.permission.MICROPHONE

  • 创建 speechRecognizer 引擎

  • 监听识别结果并回传 Flutter

也就是说,Flutter 负责“我要语音输入这个能力”,ArkTS 负责“把鸿蒙的语音识别真正调起来”。

这也是这类项目里比较常见的一种边界划分方式。

例子二:文本转语音

Flutter 侧接口依然保持极薄:

文件:app/lib/core/platform/text_to_speech_channel.dart

class TextToSpeechChannel {
  static const _channel = MethodChannel('com.foodvoyage.text_to_speech');

  static Future<void> speak(String text) async {
    await _channel.invokeMethod<void>('speak', {'text': text});
  }
}

ArkTS 侧则负责:

  • 创建 TTS 引擎

  • 设置监听器

  • 发起 speak

  • 处理 stoponErrorshutdown

文件:app/ohos/entry/src/main/ets/plugins/TextToSpeechPlugin.ets

这种分层方式在真实项目里比较常见,因为它让:

  • Flutter 页面保持清爽

  • 原生复杂性被隔离

  • 后续扩展音色、语言、播放策略也有明确落点

例子三:系统级页面跳转

食界探味 还接了 Intents Kit 方向的导航能力。

Flutter 侧:

  • 负责把 pageId 映射成具体路由

  • 在 AI 页、搜索页、详情页之间完成实际导航

文件:app/lib/core/platform/intent_navigation_channel.dart

ArkTS 侧:

  • 负责接收系统入口产生的跳转意图

  • 在 Flutter 引擎未就绪时缓存 pending navigation

  • 引擎 ready 后再把跳转结果推给 Flutter

文件:app/ohos/entry/src/main/ets/plugins/IntentNavigationPlugin.ets

这说明什么?

说明即便是“被 HarmonyOS 系统理解”这种能力,也不要求整个项目重写成 ArkTS。只要边界设计对了,Flutter 依然可以做主业务层。

4. 我不仅在做 App,也在做一套可持续内容资产

这是一个很容易被忽略的点。

食界探味 不是纯内部项目,它还天然承担:

  • 教程素材

  • 比赛方案

  • 文档沉淀

  • 内容连载

仓库里已经有很多文档资产:

  • docs/competition/

  • docs/prd/

  • docs/content/

对于这种项目来说,Flutter 还有一个额外特点:

相关开发者基础更广,已有经验和现成资料也更容易复用。

如果我全量 ArkTS,当然能写鸿蒙原生教程,但它的读者面会更窄,迁移门槛也更高。
而如果我用 Flutter 做主体,再把鸿蒙差异化能力拆开来讲,那么内容可以同时覆盖:

  • Flutter 开发者

  • 鸿蒙迁移开发者

  • 比赛项目开发者

  • 想做多端业务的团队

从内容沉淀和协作角度看,这种结构也更容易复用已有材料。

5. 多平台保留能力,本身就是产品价值

根目录 README.md 已经写得很清楚:

  • 目标平台是 HarmonyOS

  • 同时保留 Android / iOS 支持

这件事会直接影响技术路线判断。

因为一旦你选择全量 ArkTS,基本就默认接受:

  • HarmonyOS 是你的唯一主平台

  • 其他平台要么放弃,要么重新维护

但像食界探味这种内容和探索型产品,通常更容易采用:

  • 先保留多平台可用性

  • 再突出鸿蒙差异化体验

也就是说,HarmonyOS 在这里不是“唯一平台”,而是“重点平台 + 差异化平台”。
Flutter 比较容易支撑这种策略。

那什么时候我会考虑直接上全量 ArkTS?

说到这里,也要讲清楚边界。不是所有项目都适合 Flutter 主体。

如果你满足下面几种情况,我会更认真考虑全量 ArkTS:

1. 项目重度依赖鸿蒙独占能力

如果你的核心体验几乎全部依赖:

  • 复杂 Form / 卡片交互

  • 原子化服务形态

  • 深度系统协同

  • 分布式设备联动

  • 大量 Ability 生命周期控制

那原生实现通常会更直接。

2. 团队本身就是鸿蒙原生团队

如果团队没有 Flutter 资产,或者长期维护能力主要集中在 ArkTS,那么直接使用原生路线也很常见。

3. 你做的是系统级、重性能、强平台耦合产品

例如特别依赖底层窗口、设备能力、系统调度的产品,全量原生通常更利于控制。

4. 你不打算保留 Android / iOS 路线

如果 HarmonyOS 就是唯一目标平台,那么用原生也完全合理。

所以,这不是“Flutter 一定比 ArkTS 好”,而是:

对 食界探味 这个项目来说,Flutter 主体更符合当前阶段目标。

我给自己的技术边界原则

在这个项目里,我实际遵循的是下面这套边界:

放在 Flutter 的东西

  • 页面 UI

  • 路由组织

  • 状态管理

  • 业务模型

  • 网络访问

  • AI 交互

  • 大部分用户流程

放在 ArkTS 的东西

  • HarmonyOS 特有系统能力

  • 插件生命周期

  • 权限申请

  • Speech Kit / TTS / Device Security Kit / Intents Kit 等具体调用

  • FormAbility / EntryAbility 这类系统入口

不要混写的东西

  • 不要把业务判断大规模塞进 ArkTS

  • 不要让 Flutter 直接知道太多原生实现细节

  • 不要把原生插件做成第二套业务层

这个边界一旦建立起来,后面的维护会轻很多。

常见坑

这是我觉得最容易踩的几类坑。

坑 1:把“接入鸿蒙”理解成“必须全量重写”

这是最常见的误区。
很多团队真正需要的不是“重写”,而是“迁移 + 增量能力接入”。

坑 2:平台通道设计过粗

比如你把一个大而全的业务对象直接扔给原生,让原生替你做一堆页面和流程判断。这样最后 ArkTS 会迅速膨胀。

正确做法是像当前项目这样:

  • Flutter 侧暴露小而清晰的调用接口

  • ArkTS 侧只负责能力实现与结果回传

坑 3:Flutter 和 ArkTS 边界不清

如果一会儿 Flutter 管导航,一会儿 ArkTS 也管导航;一会儿 Flutter 管状态,一会儿原生也偷偷改状态,最终一定会乱。

坑 4:只关注“能跑起来”,忽略“能长期维护”

一个 Demo 跑起来不难,难的是:

  • 文章能不能继续写

  • 项目能不能继续扩

  • 新能力接入时会不会越来越脆

所以工程边界要一开始就想清楚。

可复用判断模板

如果你也在判断“该 Flutter 主体还是全量 ArkTS”,我建议先问自己 6 个问题:

  1. 现有业务资产是不是已经在 Flutter 上

  2. 主要复杂度是在业务层,还是系统层

  3. HarmonyOS 能力是核心产品本体,还是差异化增量

  4. 是否要保留 Android / iOS

  5. 团队的主技术栈更偏 Flutter 还是 ArkTS

  6. 项目当前阶段更需要“快速验证”还是“深度系统耦合”

如果你的答案更偏向:

  • 有 Flutter 资产

  • 业务复杂度更高

  • 要保留多平台

  • 鸿蒙能力是增量亮点

那大概率会走向:

Flutter 主体 + ArkTS 按需桥接

一句话原则

可以把这件事概括成一句话:

能在 Flutter 里稳定完成的业务,不下沉;只有明确依赖 HarmonyOS 系统能力的部分,才下沉到 ArkTS。

本篇总结

这篇文章讨论的重点,不是 ArkTS 是否更好,而是食界探味这个项目在当前阶段,为什么没有直接走全量 ArkTS,而是采用“Flutter 负责业务层、ArkTS 负责系统能力桥接”的结构。

这条路线让我同时拿到了几件事:

  • 业务层复用率相对更高

  • 迭代节奏更容易维持

  • 平台能力边界更容易收口

  • 多平台保留空间更大

  • 文档和教程资产更容易持续积累

如果你手里也已经有 Flutter 资产,或者当前阶段更关注“先完成完整产品,再逐步增加鸿蒙系统能力”,那么这种结构可以作为一种参考。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐