蓝牙 SDK 跨平台分层设计:Flutter 接入 Android & iOS 蓝牙 SDK 的方案设计
首先,本文介绍了跨平台分层设计的背景;然后,表达了当前正面临 Flutter 接入 SDK 这一困难;进一步地,提出了跨平台分层设计的思路,以及讨论了在 Flutter 上调用特定平台代码的方案选择;最后,用具体业务和代码论证了此方案的可行性。
目录
4.1 Pigeon 对比 MethodChannel 的优势
首先,本文介绍了跨平台分层设计的背景;然后,表达了当前正面临 Flutter 接入 SDK 这一困难;进一步地,提出了跨平台分层设计的思路,以及讨论了在 Flutter 上调用特定平台代码的方案选择;最后,用具体业务和代码论证了此方案的可行性。
一、设计需要考虑的点
-
Flutter 统一业务入口;
-
区分 Android 和 iOS 的 SDK;
-
V1 和 V2 协议不兼容,需要区分 ;
-
V1 或 V2 新增业务协议,改动要少;
-
未来 SDK 如果被 KMP 替换,Flutter 不需修改。
1.1 核心考虑
-
上层永远不知道下层细节
-
协议变化永远不会影响 Flutter
-
Flutter 只关心「业务动作」,Native 内部拆成「多条协议」
1.2 业务流程全放 Flutter 不太优雅
await sendCmd(CmdV2ConvInviteReq());
await waitAck();
if (isAccepted) {
await sendCmd(CmdV2ConvActionReq());
}
问题是:
-
Flutter 线程模型不适合精细设备时序
-
错误重试、丢包、ACK 超时很难统一
-
iOS / Android 行为不一致
-
Flutter 代码变成“协议脚本”
二、Flutter 接入 SDK 的方案
方案一:每个 SDK 都新建一个 Flutter Plugin 项目,最后引入到 Flutter 工程中:https://juejin.cn/post/7165732423534460965
dependencies:
my_flutter_plugin:
path: ../my_flutter_plugin
方案二:基于原有 Flutter 项目结构,在 Android 和 iOS 模块分别引入 SDK:
-
Android 端/iOS 端,各自接入对应蓝牙 SDK;
-
Flutter 将业务指令分发到对应 Android 端/iOS 端;
-
Flutter 声明业务意图 + Native 执行 SDK 具体业务。
方案选择:对于一定会打包进应用的 SDK,可以直接在 Flutter 目录引入;对于不一定会打包进应用的 SDK,建议每个 SDK 新建一个 Plugin 方式去引入。
👉 建议使用方案一,虽然蓝牙 SDK 是应用核心模块,一定会打包进去,但为方便移植和解耦,还是建议新建 Plugin 的方案。
三、蓝牙 SDK 跨平台分层设计
业务层——蓝牙组件层——平台兼容层——V1 / V2 协议分发层——蓝牙 SDK
-
业务层:不感知协议版本(V1 / V2),不感知平台(Android / iOS),只表达业务意图,比如:“我要发通知”,“我要获取 AR 眼镜设备信息”;
-
蓝牙组件层:BluetoothService 统一入口,把业务意图封装成 Command,与具体业务解耦;
-
平台兼容层:使用 Pigeon / MethodChannel,从 Flutter → Native 透传,不做协议判断;
-
V1 / V2 协议分发层:Native 层 Android / iOS 端决定使用哪个协议编码;
-
蓝牙 SDK:将 Byte 发给 AR 眼镜,Android → .aar,iOS → .xcframework。

四、Flutter 调用特定平台的代码
4.1 Pigeon 对比 MethodChannel 的优势
|
特性 |
Pigeon |
MethodChannel |
|
类型安全 |
✅ 强类型约束 |
❌ 容易传错类型 |
|
拼写错误 |
✅ 编译时报错 |
❌ 运行才报错 |
|
开发效率 |
✅ 自动生成代码 |
❌ 需要手动序列化 |
|
维护难度 |
✅ 结构清晰,易于维护 |
❌ 随着接口增多变乱 |
4.2 跨端通信方案选择指南
|
场景 |
是否推荐 Pigeon |
是否推荐 MethodChannel |
说明 |
|
蓝牙 SDK 对外能力 (connect / send) |
✅ |
❌ |
稳定性优先:SDK 接口需要严格的类型约束,防止版本断层。 |
|
业务级指令 (Notify / Call / Control) |
✅ |
❌ |
业务契约:使用 Pigeon 定义协议,两端同步更新,减少沟通成本。 |
|
Flutter ↔ Native 数据模型 |
✅ |
❌ |
强类型:自动生成 Model 类,避免手动解析 Map 导致的字段错误。 |
|
设备状态回调 (连接状态、电量) |
✅ |
❌ |
FlutterApi:利用 Pigeon 的反向调用机制,结构化下发状态更新。 |
|
少量、固定指令 (如:获取版本号) |
✅ |
❌ |
工程规范:即便是小功能,使用 Pigeon 也能保持全局代码风格统一。 |
|
SDK 封装层 (三方地图、支付) |
✅ |
❌ |
标准接入:插件开发标配,确保开发者调用时的 API 提示友好。 |
|
协议调试 / 临时命令 |
❌ |
✅ |
快速验证:无需运行脚本生成代码,随写随测,适合敏捷开发。 |
|
非结构化 Map 透传 |
❌ |
✅ |
灵活性:数据结构极其不固定或嵌套过深时,手动处理更直观。 |
|
高频、大数据流 (PCM / SCO) |
❌ |
⚠️ (EventChannel) |
性能瓶颈:Pigeon 的序列化开销不适合流式数据,应选 EventChannel。 |
|
动态协议 (灰度 / 远程配置) |
❌ |
✅ |
动态性:Pigeon 依赖编译时生成,无法处理云端动态下发的字段。 |
|
C++ / JNI SDK 透传 |
❌ |
✅ |
透传层:Native 层只是个搬运工,没必要在中间层再做一次强类型定义。 |
注:官方介绍:在 Flutter 中使用特定于平台的原生自定义代码
五、业务实现-时序图
5.1 AR 眼镜电量获取-时序图

5.2 推送通知到 AR 眼镜-时序图

小结
-
SDK 需接入到 Android / iOS 原生工程,不能直接被 Flutter 使用;
-
Flutter 与 Android / iOS 原生跨端通信,需要结合 Pigeon 和 MethodChannel 方案;
-
本设计方案是基于原有 Flutter 项目结构,新建 Plugin 分别在 Android 和 iOS 中引入 SDK。
更多推荐



所有评论(0)