在 Flutter 项目中,只要涉及 系统能力、硬件设备、第三方 SDK、音视频、蓝牙、串口、机器人控制 ,就绕不开一个核心问题:
👉 Flutter 如何与 Android / iOS 原生通信?
Flutter 官方提供了三种 Platform Channel:
-
MethodChannel
-
EventChannel
-
BasicMessageChannel
很多教程只停留在"怎么用",但在中大型项目里,更重要的是:
✅ 选型
✅ 架构职责
✅ 通信模型
✅ 性能边界
✅ 工程落地方式
本文从工程视角 + 架构视角,带你一次彻底搞懂。
一、三种 Channel 总览
Flutter 中所有跨端通信,本质都是:
👉 Dart VM ↔ 原生 Runtime 的消息传递
官方封装了三种语义层模型:
| Channel | 核心定位 | 通信模型 |
|---|---|---|
| MethodChannel | 调用原生能力 | 函数调用 / RPC |
| EventChannel | 原生持续推送 | 订阅 / 数据流 |
| BasicMessageChannel | 自由通信 | 消息总线 / 管道 |
一句话总结:
Method = 调用
Event = 监听
Basic = 自由通信
二、MethodChannel ------ 跨端 RPC / 能力调用
最常用,90% 插件的核心。
典型场景
- 获取系统信息
- 调用蓝牙 / 相机 / 定位
- 控制设备
- Flutter 调原生
- 原生反调 Flutter
Flutter 端
Dart
static const channel = MethodChannel('robot/control');
final result = await channel.invokeMethod('move', {
'x': 10,
'y': 20,
});
Android 端
Dart
MethodChannel(flutterEngine.dartExecutor, "robot/control")
.setMethodCallHandler { call, result ->
when(call.method) {
"move" -> {
val x = call.argument<Int>("x")
result.success("ok")
}
else -> result.notImplemented()
}
}
工程特性
-
方法名 + 参数 + 返回值
-
支持异常 / 成功 / 未实现
-
天然 async/await
-
强语义接口模型
架构对标
| Flutter | 传统架构 |
|---|---|
| MethodChannel | HTTP / AIDL / gRPC |
👉 本质:跨语言 RPC。
三、EventChannel ------ 原生事件流 / 状态流
专门解决:
👉 原生持续往 Flutter 推数据
典型场景
- 传感器
- 蓝牙连接状态
- 串口数据
- 网络变化
- MQTT 推送
- 硬件回调
Flutter 端
Dart
EventChannel channel = EventChannel('robot/event');
channel.receiveBroadcastStream().listen((event) {
print("收到原生事件: $event");
});
Android 端
Kotlin
EventChannel(flutterEngine.dartExecutor, "robot/event")
.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(args: Any?, events: EventChannel.EventSink) {
callback = events
}
override fun onCancel(args: Any?) {
callback = null
}
})
推送数据:
Kotlin
callback?.success(data)
工程特性
- 单向推送(原生 → Flutter)
- 多次发送
- Stream 模型
- 自动感知订阅/取消
架构对标
| Flutter | 传统架构 |
|---|---|
| EventChannel | MQTT / RxBus / Listener / 数据总线 |
👉 本质:跨端事件总线。
四、BasicMessageChannel ------ 消息通道 / 自定义协议
最底层、最自由、也最容易被低估。
典型场景
- 自定义通信协议
- 大数据通信
- 二进制数据
- 多轮对话
- Flutter ↔ 原生对等通信
- 视频帧 / 设备报文
Flutter 端
Dart
final channel = BasicMessageChannel(
'robot/bus',
StandardMessageCodec(),
);
channel.send({"cmd": "ping"});
channel.setMessageHandler((message) async {
print("来自原生: $message");
return "pong";
});
Android 端
Kotlin
BasicMessageChannel(
flutterEngine.dartExecutor,
"robot/bus",
StandardMessageCodec()
).setMessageHandler { message, reply ->
Log.e("msg", message.toString())
reply.reply("pong")
}
工程特性
- 双向对等
- 无 method 语义
- 可选多种 Codec(String / JSON / Binary)
- 更接近底层通信模型
架构对标
| Flutter | 传统架构 |
|---|---|
| BasicMessageChannel | TCP / WebSocket / 串口协议 / EventBus |
👉 本质:跨端消息通道。
五、从工程角度如何选?
| 场景 | 推荐 |
|---|---|
| 系统能力调用 | MethodChannel |
| 设备控制命令 | MethodChannel |
| 持续状态 / 监听 | EventChannel |
| 设备数据流 | EventChannel |
| 自定义协议 | BasicMessageChannel |
| 视频/音频/大数据 | BasicMessageChannel + BinaryCodec |
六、高级理解:三者底层是同一套系统
很多人不知道:
MethodChannel / EventChannel / BasicMessageChannel
底层其实全是:
👉 BinaryMessenger + Codec
只是 Flutter 官方帮你封装了三种语义层模型。
关系本质:
-
MethodChannel = 带"方法语义"的 MessageChannel
-
EventChannel = 带"订阅模型"的 MessageChannel
-
BasicMessageChannel = 原始消息通道
👉 EventChannel 底层也是 message channel。
七、企业级插件常见架构模式
真正复杂插件,很少只用一种。
常见组合:
| 职责 | Channel |
|---|---|
| 控制类接口 | MethodChannel |
| 状态监听 | EventChannel |
| 数据通道 | BasicMessageChannel |
示例:设备型插件
Kotlin
MethodChannel → connect() / move() / stop()
EventChannel → onStatus / onError / onState
BasicMessage → 原始设备数据流 / 视频帧
这套结构,在机器人、蓝牙、音视频、车机、物联网插件里非常常见。
八、性能与边界(工程必须知道)
⚠️ Channel 不是"无限快"
- 跨语言
- 跨线程
- 有序列化成本
- 有内存拷贝成本
不适合:
- 高频视频帧
- 大规模内存搬运
- 毫秒级实时控制
正确姿势:
- 控制走 Channel
- 大数据留在原生
- Flutter 只接收"结果态"
或走:
- FFI
- 共享内存
- 原生渲染层
九、终极一句话总结
Flutter 与原生通信的本质,不是"调 API",
而是:
👉 在 Dart VM 与原生 Runtime 之间,构建了一套"跨进程消息系统"。
你不是在"用工具",
你是在设计通信协议与系统边界。
下一篇: