适合谁看

  • 正在设计 Flutter 平台桥接层的人

  • 不确定平台能力文件该放哪、该怎么命名的人

  • 已经有多个原生通道,想做一次整理的人

  • 正在写鸿蒙 Flutter 平台桥接层的人

问题背景

平台能力层最怕三种写法:

  • 按页面命名

  • 按临时需求命名

  • 一个文件里揉多个不相关能力

这样一来,平台桥接层很快就会失去可读性。

而在鸿蒙 Flutter 项目里,问题还会继续加重,因为这里的“平台能力”往往同时要承接:

  • MethodChannel 调用

  • 系统入口参数

  • 原生事件回推

  • 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

对应的鸿蒙原生侧则在:

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

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

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

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

核心实现

如果这篇只讲“命名要统一”,其实还是不够。
对鸿蒙教程来说,更重要的是回答:

  • 为什么这层必须存在

  • 为什么它既不能退回页面层,也不能直接和 ArkTS 插件混在一起

  • 为什么命名规则会直接影响后面 HarmonyOS 能力扩展

一、优先按“能力本身”命名,而不是按页面或产品场景命名

当前命名不是:

  • ai_voice_helper.dart

  • collection_safe_page_bridge.dart

而是直接围绕能力:

  • speech_recognition_channel

  • text_to_speech_channel

  • intent_navigation_channel

  • anti_peep_protection_channel

这很重要,因为能力可以复用到多个页面。
在鸿蒙项目里,这一点尤其关键。
因为像:

  • 语音识别

  • TTS

  • Intent 导航

  • 防窥保护

本质上都不是某一个页面专属的,而是 HarmonyOS 能力在 Flutter 侧的桥接出口。

二、文件名直接体现“这是桥接层”,让人一眼知道它属于 Flutter 与鸿蒙之间

当前统一用了 channel
它的好处是很直观:

  • 这不是业务 service

  • 这不是页面 controller

  • 这是 Flutter 和 HarmonyOS 原生之间的通道层

当前项目里,这套命名还能和 ArkTS 原生侧形成非常清楚的映射:

  • speech_recognition_channel.dartSpeechRecognitionPlugin.ets

  • text_to_speech_channel.dartTextToSpeechPlugin.ets

  • intent_navigation_channel.dartIntentNavigationPlugin.ets

  • anti_peep_protection_channel.dartAntiPeepProtectionPlugin.ets

只要文件名能一一对上,后面排错和扩展都会轻很多。

三、接口尽量保持薄,但要足够承接鸿蒙入口和事件模型

这些文件大多只做几件事:

  • 调用 MethodChannel

  • 解析参数

  • 做少量平台兼容兜底

复杂业务逻辑不会放在这里。
这能避免平台层越写越胖。

不过“保持薄”不等于只包一层 invokeMethod
在鸿蒙项目里,平台层有时还需要承接:

  • pending navigation 的消费

  • pageId -> route 的翻译

  • 事件回推转页面可消费状态

例如 intent_navigation_channel.dartanti_peep_protection_channel.dart 就明显比单纯的一次调用复杂,但它们仍然没有越界去写页面业务。

四、把跨入口逻辑单独封在能力层里,因为鸿蒙系统入口不是普通页面跳转

比如 intent_navigation_channel.dart 不只是简单桥接,它还处理:

  • pageId 映射

  • pending navigation 消费

  • 详情页特殊跳转

这说明平台层里也可以有“和入口强相关的桥接逻辑”,但仍然不应该越界成页面业务层。

当前项目里这条链之所以值得单独讲,就是因为它还和鸿蒙原生侧入口配合得很紧:

  • EntryAbility.ets 接冷启动和热入口

  • InsightIntentExecutorImpl.etspageId / dishId 校验

  • IntentNavigationPlugin.ets 负责转发或暂存

  • intent_navigation_channel.dart 再把原生语义翻成 GoRouter 动作

这说明平台能力层在鸿蒙项目里,不只是“调原生 API”,还要负责承接系统入口语义。

五、这层命名和封装规则,决定了第二批鸿蒙能力还能不能继续扩

一个鸿蒙 Flutter 项目最容易出问题的时候,不是第一条 channel 刚写出来的时候,而是第二批、第三批能力继续接入的时候。

如果第一批就已经做到:

  • 按能力命名

  • 按 bridge 身份命名

  • 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

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

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

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

鸿蒙侧实现

鸿蒙原生侧已经把插件按能力拆开了:

  • SpeechRecognitionPlugin.ets

  • TextToSpeechPlugin.ets

  • IntentNavigationPlugin.ets

  • AntiPeepProtectionPlugin.ets

Flutter 侧按同样思路命名和封装,层间映射会更清晰。
这件事在鸿蒙项目里很重要,因为它能保证:

  • Flutter 和 ArkTS 两边说的是同一套能力语言

  • 入口逻辑、能力逻辑、事件逻辑不会在命名层就开始混淆

Flutter 侧实现

更稳的做法通常是:

  • 一个能力一个 channel 文件

  • 文件名直接说明能力

  • 页面不要自己 new 原生桥接对象

这正是当前项目的基本方向。
而放到鸿蒙 Flutter 项目里,它还可以再补一条:

  • Flutter 平台层只负责桥接和少量语义翻译,真正的 HarmonyOS 系统能力实现仍留在 ArkTS

常见坑

  • 按页面或业务场景命名平台桥接文件

  • 多个不相关能力共用一个“system_service”

  • 平台通道里塞大量业务流程代码

  • 命名看不出这是桥接层还是服务层

  • Flutter 侧文件名和 ArkTS 插件名完全对不上,最后一条链两头找不到

  • 鸿蒙系统入口逻辑被塞进页面或业务 service,导致平台层名义上存在,实际上空心化

可复用模板

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

  static Future<String> startListening() async {
    final result = await _channel.invokeMethod<String>('startListening');
    return result ?? '';
  }
}
Flutter:xxx_channel.dart
ArkTS:XxxPlugin.ets
Entry:EntryAbility / InsightIntentExecutor 处理系统入口

平台层负责桥接和语义翻译
页面层只消费整理后的能力

本篇总结

  • 平台能力层应该按能力命名,而不是按页面命名

  • 对鸿蒙 Flutter 项目来说,这一层本质上是在管理 Flutter 与 HarmonyOS 原生层之间的稳定边界

  • 只要平台层保持薄、按能力拆、命名清楚,并且能和 ArkTS 插件一一对应,后面维护会轻很多

Logo

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

更多推荐