目录
[2.1 第一层:应用入口层](#2.1 第一层:应用入口层)
[2.2 第二层:业务层](#2.2 第二层:业务层)
[2.3 第三层:业务组件层](#2.3 第三层:业务组件层)
[2.4 第四层:中间件层](#2.4 第四层:中间件层)
[2.5 第五层:基础组件层](#2.5 第五层:基础组件层)
[四、状态管理:MVVM + Provider 的实践](#四、状态管理:MVVM + Provider 的实践)
------------------------参考------------------------
[Flutter 平台架构图](#Flutter 平台架构图)
[Android 平台架构图](#Android 平台架构图)
写在前面
作为一个面向智能眼镜设备的 Flutter 应用,MYGlass 的架构设计经历了多次迭代。从最初简单的模块化结构,到现在的多层组件化设计,我们踩过不少坑,也积累了一些经验。这篇文章想和大家分享一下我们在架构设计上的思考和实践。
一、架构设计的核心原则
在开始设计架构之前,我们明确了几个核心原则:
- 高内聚低耦合:每个模块只负责自己的领域,避免跨模块的直接依赖;
- 可扩展性:新功能可以快速加入,不影响现有代码;
- 可测试性:模块之间依赖抽象,方便单元测试和集成测试;
- 渐进式分层:从底层到上层,依赖关系清晰。
二、五层架构详解

2.1 第一层:应用入口层
这是整个应用的起点,包含三个文件,分别是国内版 main.dart、国际版 main_intl.dart、多版本共有main_app.dart,如下是国内版 main.dart入口:
// main.dart - 国内版入口
void main() async {
AppFlavor.appFlavor = Flavor.cn;
await runMyApp(ModuleRoutesCn.routes, initFlavorImpl: () async {
await _initMicrosoftSpeech();
await _initBaiduMap();
});
}
- 通过 Flavor 区分国内版和国际版;
- initFlavorImpl 允许不同版本初始化不同的 SDK;
- 所有初始化逻辑都在 main_app.dart 中统一管理。
2.2 第二层:业务层
这是应用的核心,包含了所有业务模块:
|---------------------|----------|--------------------------------|
| 模块 | 功能定位 | 核心职责 |
| mb_app | 主应用 | 首页、设备管理、相册、联系人、通知、电话转写、设置等通用功能 |
| mb_account | 用户体系 | 登录、注册、用户信息管理 |
| mb_assistant | AI 助手 | 语音交互、图像识别、智能问答等 AI Agent 功能 |
| mb_teleprompter | 提词器 | 演讲提词、实时字幕 |
| mb_translate | 翻译服务 | 实时翻译、语音转写 |
| mb_live | 直播模块 | 视频直播、推流 |
| mb_notes | 记录功能 | AI 助手记录、翻译记录、语音录入 |
实际场景:比如 AI 助手模块,它需要和蓝牙通信、语音服务、摄像头服务等多个组件交互,但这些依赖都通过抽象接口注入,模块本身不直接依赖具体实现。
2.3 第三层:业务组件层
这一层封装了与硬件和第三方服务相关的能力:
// 蓝牙组件示例
class BTReceiveDataService {
static final instance = BTReceiveDataService._();
Stream<Map<String, dynamic>> get req => _reqController.stream;
Stream<ConnectState?> get connectState => _connectController.stream;
// 订阅眼镜发送的指令
void listenToDeviceCommands() {
_eventChannel.receiveBroadcastStream().listen((event) {
final type = event['type'] as String;
switch (type) {
case 'simultaneousAction':
_handleTranslateEvent(event);
break;
case 'teleprompterActionReq':
_handleTeleprompterEvent(event);
break;
}
});
}
}
- 每个组件都是单例,避免重复创建;
- 通过 Stream 实现响应式通信;
- 抽象硬件差异,提供统一接口。
2.4 第四层:中间件层
这一层包含基础工具和路由管理:
mb_base 的核心功能:
- 全局常量定义(颜色、尺寸、URL 配置)
- 生命周期管理(应用前后台监听)
- 放置各模块可共用的代码
mb_router 使用 GoRouter 实现声明式路由:
class MainRouter {
static GoRouter createRouter(List<RouteBase> moduleRoutes) {
return GoRouter(
navigatorKey: MBToast.rootNavigatorKey,
initialLocation: '/',
observers: [MyRouteObserver()],
routes: [
GoRoute(path: '/', builder: (_, __) => const SplashPage()),
...moduleRoutes,
],
);
}
}
2.5 第五层:基础组件层
这是整个应用的基石,包含六大核心组件:
|-----------------|--------|-------------------|
| 组件 | 作用 | 技术选型 |
| mb_ui | UI 组件库 | 自定义 Widget |
| mb_log | 日志系统 | 自定义实现 |
| mb_sp | 本地存储 | SharedPreferences |
| mb_db | 数据库 | Drift |
| mb_network | 网络请求 | Dio |
| mb_eventbus | 事件总线 | 基于 Stream 自定义实现 |
网络层封装示例:
class NetworkClient {
Future<Result<dynamic, NetworkError>> request(Requestable request) async {
try {
final response = await _dio.request(
request.url,
data: request.parameters,
options: Options(method: request.method.rawValue),
);
return Success(response.data);
} on DioException catch (e) {
return Failure(NetworkError.fromDio(e));
}
}
}
三、启动流程:从冷启动到首页
应用启动是一个复杂的过程,我们把它分成了四个阶段:
阶段1: Flutter引擎初始化
↓
阶段2: 核心服务启动(主题、语言、日志、存储)
↓
阶段3: 业务服务启动(网络、登录状态、设备管理)
↓
阶段4: 后台服务启动(三方SDK、任务管理器)
关键代码:
// main_app.dart
Future<void> runMyApp(List<RouteBase> moduleRoutes) async {
// 阶段1:绑定引擎
WidgetsFlutterBinding.ensureInitialized();
// 阶段2:核心服务
await themeProvider.loadTheme();
await LogManager().initialize();
await SPUtils.init();
// 阶段3:业务服务
NetworkClient.init(baseUrl: Config.accountV2HostProd);
await loginViewModel.initData();
// 启动应用
runApp(MultiProvider(providers: [...], child: MyApp()));
// 阶段4:后台服务
WidgetsBinding.instance.addPostFrameCallback((_) {
await MBTaskManager.instance.init();
});
}
四、状态管理:MVVM + Provider 的实践
我们采用了 MVVM 模式,配合 Provider 进行状态管理:
abstract class BaseViewModel<T> extends ChangeNotifier {
ViewState<T> _state = const Idle();
Future<void> safeRequest(Future<Result<T?, NetworkError>> Function() request) async {
try {
setLoading();
final result = await request();
result.fold(
onSuccess: (data) => setSuccess(data),
onFailure: (e) => setError(e),
);
} catch (e) {
setError(e);
}
}
}
使用示例:
class LoginViewModel extends BaseViewModel<LoginResponse> {
Future<void> login(String phone, String code) async {
await safeRequest(() => LoginRequest(phone, code).execute());
}
}
五、跨模块通信:事件总线模式
当多个模块之间需要通信,但又不想产生直接依赖时,事件总线是个好选择:
// 定义事件
class TokenInvalidEvent extends AppEvent {
final int code;
final String message;
TokenInvalidEvent(this.code, {this.message = ''});
}
// 触发事件
AppEventBus.instance.fire(TokenInvalidEvent(401, message: '登录过期'));
// 监听事件
AppEventBus.instance.on<TokenInvalidEvent>().listen((event) {
router.go('/login');
});
六、总结
架构设计不是一蹴而就的,它需要随着业务发展不断演进。MYGlass 的五层架构是我们在实践中逐步完善的结果,虽然还有不少可以改进的地方,但总体来说满足了当前的业务需求,也为未来的扩展打下了良好基础。
如果你正在开发类似的 Flutter 应用,希望这篇文章能给你一些启发。架构没有银弹,适合自己业务的才是最好的。
------------------------参考------------------------
业务需求脑图

Flutter 平台架构图

Android 平台架构图
