898 字
4 分钟
Flutter跨端应用的架构设计
前言
接触 Flutter 框架时,最吸引我的地方就是多平台能力和跨端能力,并且他也是移动端应用比较主流的框架。
一套代码编译多端应用。
Android、iOS、Windows、macOS、Linux,甚至 Web,都可以使用同一套 Flutter 代码构建应用。如果全部都使用纯Dart语言实现的话,会非常方便和效率。
但随着项目复杂度不断提高,我发现这些场景不太够用,对于系统强关联和性能要求高的应用,以及云端服务,Dart就不太合适,所以就需要其他语言来处理。
例如:
文件系统,本地服务,后台任务,蓝牙通信,USB 设备,系统通知,系统权限,等等...
这些能力都带有明显的平台特征。
不同平台拥有不同的:
生命周期,权限模型,系统能力,等等...
还有一些特殊需求场景:
大规模并发,高性能网络转发,AI 推理,密码学计算,压缩算法,数据库引擎,等等...
架构理解
经过不断的学习和摸索,我大致理解了这些大型商业架构模式的思想。
其实很多跨端框架都是UI层面和业务层面的,系统层面和核心能力需要抽象出来,然后封装一个统一接口供业务层面调用。
大致思路:
Flutter负责UI和业务逻辑,接口层负责平台差异,跨平台语言负责真正的后端运行。
对于需要调用系统能力的后端,我觉得最好是使用跨平台能力优秀的编译型语言,例如go,rust,C,C++
其他解释型语言对于跨平台不太友好。当然并不是不能跨,只是考虑到各个平台的原生产物,SDK 化、服务化和跨平台分发不太友好而已,而且因为运行时的原因,通常性能和资源占用也不太友好。
以下以go语言为后端示例,其他语言思路也差不多。
流程如下:
App 启动
↓
初始化依赖注入 / 配置 / 存储
↓
注册当前平台的 RuntimeService
↓
加载 Flutter UI
↓
用户操作 UI
↓
ViewModel 处理状态与交互
↓
UseCase / Repository 执行业务逻辑
↓
调用统一 RuntimeService 接口
↓
Platform Adapter 适配当前平台
↓
调用原生内核
Android → AAR / .so
Windows → exe
Linux → binary
macOS → binary / framework
iOS → XCFramework / NetworkExtension
↓
内核回传状态 / 日志 / 错误 / 流量统计
↓
RuntimeService 统一转换为 Dart Model / Stream
↓
ViewModel 更新状态
↓
UI 自动刷新
最简结构:
lib/
├── main.dart
├── ui/ # 页面、组件、ViewModel
├── domain/ # Model、UseCase、抽象接口
├── data/ # Repository、Service实现
└── platform/ # Android/Windows/Linux/macOS/iOS 适配器
后端封装统一接口
Android / iOS: Go 内核 SDK 化,做成 AAR / XCFramework
Windows / macOS / Linux: Go 内核 daemon 化,本地 Socket IPC调用
然后Flutter层调用统一接口。
这里更建议桌面端优先使用 Unix Socket / Named Pipe 进行IPC互相通信,而非 127.0.0.1 TCP。
因为无需开放端口、性能更高、安全性更好,冲突也能更少,也更符合本地进程通信场景。
当然需要对接公网后端服务的话除外。
后端封装接口 - 代码结构示例
core/
├─ runtime/ # 纯 Go 核心逻辑:启动、停止、reload、状态、日志
├─ api/ # 统一接口定义
├─ mobile/ # Android/iOS 导出层:AAR / XCFramework
├─ daemon/ # Windows/macOS/Linux 守护进程入口
└─ ipc/ # 桌面 IPC:Named Pipe / Unix Socket
