一、关键源码入口
1. 路由生命周期管理 Mixin
dartCopy Code
mixin PageRouteReportMixin<T> on Route<T> {
@override
void install() {
super.install();
RouterReportManager.reportCurrentRoute(this);
}
@override
void dispose() {
super.dispose();
RouterReportManager.reportRouteDispose(this);
}
}
2. GetPageRoute 核心实现
dartCopy Code
class GetPageRoute<T> extends PageRoute<T>
with GetPageRouteTransitionMixin<T>, PageRouteReportMixin {
@override
void dispose() {
super.dispose();
final middlewareRunner = MiddlewareRunner(middlewares);
middlewareRunner.runOnPageDispose();
}
}
二、引言:Bindings 的魔法
GetX 通过 **Bindings** 机制实现依赖注入与自动回收,其核心逻辑如下:
1. 单例注入原理
- **
Bindings声明**:每个路由页面关联一个 Binding 类 - 注册依赖:在
dependencies()方法中调用Get.lazyPut或Get.put - 作用域隔离:依赖项默认绑定到当前路由生命周期
dartCopy Code
class DetailBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => DetailController()); // 路由级单例
}
}
2. 自动回收机制
- 路由销毁触发:当
GetPageRoute被销毁时(页面关闭),触发RouterReportManager.reportRouteDispose - 清理策略:通过
_removeDependencyByRoute移除路由关联的控制器 - 执行顺序:
GetPageRoute.dispose()→PageRouteReportMixin→RouterReportManager→ 清理依赖
三、重点记录:不同依赖注册方式的差异
1. 三种依赖注册方式对比
三种依赖注册方式对比(修正版)
| 方法 | 是否自动销毁 | 适用场景 | 典型示例 |
|---|---|---|---|
**Get.put()** | 有条件支持 | 单例依赖,当满足以下条件时自动回收: 1. 路由销毁 2. permanent: false 3. SmartManagement.full/keepFactory | 页面级控制器,如 HomeController,需与路由绑定生命周期 |
**Get.create()** | 支持 | 动态依赖,每次调用都生成新实例,实例与调用者(如页面)绑定生命周期 | 带参数的控制器,如 UserProfileController(userId: 123) |
**Bindings 绑定** | 支持 | 路由级作用域依赖,推荐用于明确依赖与路由的绑定关系 | 跨页面共享的控制器,如 ShoppingCartController,需在多个页面间保持状态一致性 |
这里需要说明,Get.put 如果在某个Widget类中执行,只要满足单例、路由激活、非永久性条件即可自动回收。
四、MiddlewareRunner 的三大应用场景
1. 路由拦截(redirect)
dartCopy Code
class AuthMiddleware extends GetMiddleware {
@override
RouteSettings? redirect(String? route) {
if (!isLogin && route == "/profile") {
return RouteSettings(name: "/login");
}
return null;
}
}
场景:未登录用户访问个人主页时跳转登录页
2. 参数修改(onPageCalled)
dartCopy Code
class ParamsMiddleware extends GetMiddleware {
@override
GetPage? onPageCalled(GetPage? page) {
if (page?.name == "/search") {
return page?.copy(parameters: {"timestamp": DateTime.now().toString()});
}
return page;
}
}
场景:动态添加时间戳参数到搜索页面
3. 资源释放(onPageDispose)
dartCopy Code
class AnalyticsMiddleware extends GetMiddleware {
@override
void onPageDispose() {
Analytics.reportClose(Get.currentRoute);
}
}
场景:页面关闭时上报用户行为埋点
五、_removeDependencyByRoute 深度解析
1. 函数作用
清理与特定路由关联的依赖项,确保内存回收
2. 执行流程
dartCopy Code
static void _removeDependencyByRoute(Route route) {
// 清理通过 Get.create() 注册的实例
if (_routesByCreate.containsKey(route)) {
_routesByCreate[route]!.forEach((onClose) => onClose());
_routesByCreate.remove(route);
}
// 清理通过 Bindings 注册的依赖
final keys = _routesKey[route];
keys?.forEach((key) => GetInstance().delete(key: key));
_routesKey.remove(route);
}
3. 关键设计
-
双重清理机制:
- **
Get.create()实例**:直接执行注册时的onClose回调 - **
Bindings依赖**:通过GetInstance().delete()触发onClose()
- **
-
路由级作用域:确保不同路由的依赖项 完全隔离
六、总结:GetX 自动回收机制的设计哲学
-
生命周期绑定:
GetPageRoute通过重写dispose()方法,将控制器生命周期与路由销毁事件强绑定 -
中间件扩展性:
MiddlewareRunner提供可插拔的扩展点(参数修改、拦截、埋点) -
依赖治理策略:
- 全局单例由开发者手动管理
- 路由级依赖由框架自动回收
这种设计在保持灵活性的同时,最大程度避免了 Flutter 应用常见的内存泄漏问题,其实现方式与 Android 的 ViewModel + LiveData 生命周期管理有着异曲同工之妙。