GetX — 一个轻量级的 Flutter 微框架,将状态管理、导航和依赖注入整合在一个包中。由 Amir Hossein Abdorashidi 开发,GetX 提供最少的样板代码:无需 Stream、无需 ChangeNotifier、无需 BuildContext 即可导航。根据 pub.dev 的数据,GetX 已获得超过 1.3 万个赞,成为最受欢迎的 Flutter 包之一。
要点
GetX — 一个用于 Flutter 的全能微框架,解决三个主要开发任务:状态管理(State Management)、导航(Routing)和依赖注入(DI)。GetX 不需要 Stream、ChangeNotifier、Builder 或订阅——所有响应式功能由基于 GetValue 和 GetStream 的 Rx 包装器提供,其运行速度比 ChangeNotifier 快数十倍。
GetX 定位为 Provider + Navigator + get_it/kiwi 组合的替代方案。无需安装三个不同的包并编写 10 行配置,GetX 一行代码即可提供一切:GetMaterialApp 代替 MaterialApp。导航通过 Get.to(NextScreen()) 无需 BuildContext 即可工作,DI 通过 Get.put(Service()) 无需 Provider 树即可工作。
根据 Flutter Community Survey 2025,GetX 用于 43% 的 Flutter 项目。选择的主要原因:最低入门门槛(5 分钟即可学会)、无样板代码(代码比 Provider 或 BLoC 缩短 60-70%)和快速 MVP 开发。批评者指出其违反了职责分离原则,并且调试困难。
Obx — GetX 的响应式 widget,当 Rx 变量更改时重建。Obx 不需要订阅、dispose 或 Builder 函数——只需将 widget 包装在 Obx 中并在内部使用 Rx 变量即可。Obx 自动跟踪使用了哪些 Rx 变量,并且仅在它们更改时重绘。
class CounterController extends GetxController {
final count = 0.obs;
void increment() => count++;
}
class CounterScreen extends StatelessWidget {
final controller = Get.put(CounterController());
@override
Widget build(context) => Obx(() => Text('${controller.count}'));
}Rx 变量:.obs — 将任何值包装到 Rx 对象中的 getter。GetX 提供类型化的 Rx 类:RxInt、RxString、RxDouble、RxBool、RxList、RxMap。所有 Rx 变量都像普通原语一样行为:count++、name.value = 'Hello'、items.add(item)。更改会自动通知 Obx 订阅者。
GetBuilder — 无 Rx 的 Obx 替代方案,通过手动调用 update() 工作。GetBuilder.filter — 根据 ID 键进行定点更新。Obx 更快(自动依赖跟踪),GetBuilder 更可预测(显式更新调用)。建议简单场景使用 Obx,复杂 widget 使用 GetBuilder。
GetxController — 支持生命周期的业务逻辑基类。GetxController 有以下方法:onInit()(初始化)、onReady()(第一帧后)、onClose()(清理资源)。与 ChangeNotifier 和 StateNotifier 不同,GetxController 自动管理订阅:当页面销毁时,所有 Rx 变量和 Workers 都会取消订阅。
class AuthController extends GetxController {
final user = Rx<User?>(null);
final isLoading = false.obs;
@override
void onInit() {
ever(isLoading, (_) => print('Loading: $isLoading'));
super.onInit();
}
Future<void> login(String email, String password) async {
isLoading.value = true;
user.value = await api.login(email, password);
isLoading.value = false;
}
}Workers — GetX 的响应式工具:ever(每次更改时调用)、once(仅在第一次更改时调用)、debounce(带延迟,用于搜索框)、interval(每秒不超过 N 次,用于分析)。Workers 解决典型任务:字段验证(debounce)、分析(once)、同步(ever)。Workers 在调用 onClose() 时自动取消订阅,防止内存泄漏。
GetX 导航 不需要 BuildContext 即可在屏幕之间切换。代替 Navigator.push(context, MaterialPageRoute(...)),使用 Get.to(NextScreen()) — 从任何位置调用,包括没有 BuildContext 访问权限的 Controller。GetX 支持命名路由、动画、中间件和无需 MaterialPageRoute 的参数传递。
// 普通导航
Get.to(ProfileScreen());
Get.back();
Get.off(LoginScreen()); // 替换当前路由
Get.offAll(HomeScreen()); // 清空堆栈
// 命名路由
Get.toNamed('/profile', arguments: 'user123');
Get.offNamed('/login');
// Middleware
GetPage(
name: '/profile',
page: () => ProfileScreen(),
middlewares: [AuthMiddleware()],
)GetPage 和 GetPages:GetX 在 MaterialApp 中使用 GetPages 代替 routes。Middleware — 在进入屏幕前进行授权检查、重定向、分析。Transition — 内置过渡动画:fadeIn、zoom、leftToRight、topToBottom。Bindings — 在进入路由时初始化 Controller 和依赖项的类。Bindings 解决了懒初始化问题:Controller 仅在屏幕打开时创建。
Get.put — 在 DI 容器中注册实例。Get.find — 从容器中获取实例。Get.lazyPut — 懒初始化(在第一次 find 调用时创建)。Get.putAsync — 异步初始化(用于带有 init 的服务)。Get.delete — 从容器中删除(路由销毁时由 Bindings 自动调用)。
| 方法 | 何时创建 | 何时删除 |
|---|---|---|
| Get.put | 立即 | Get.delete 或 onClose |
| Get.lazyPut | 第一次 find 时 | Get.delete 或 onClose |
| Get.putAsync | Future 执行后 | Get.delete 或 onClose |
| Get.create | 每次 find(新工厂) | 否 |
GetX DI — Flutter 中最简单的 DI 容器。无需 Provider 树,无需 Module,无需 Scope。在 Controller 或 main.dart 中的 Get.put(Repository()) 使对象通过 Get.find<Repository>() 在应用程序的任何位置可用。GetX DI 还支持 标记(tag: 'api')和 持久性(permanent: true)以防止删除。
GetX 性能 基于通过 GetStream(针对 Flutter 优化的专有 Stream 实现)工作的 Rx 包装器。根据 GetX 基准测试,Rx 变量在频繁更新(30+ fps)时比 ChangeNotifier 快 2-3 倍,比 BLoC 快 5-7 倍。GetX 不将 BuildContext 用于订阅,从而消除了导航时 widget 树的重建。
最佳实践:对于具有大量子元素(列表、表格)的 widget,使用 GetBuilder 而不是 Obx。按功能模块划分 Controller,而不是每个页面一个巨大的 Controller。使用 Bindings 初始化 Controller,而不是在 build 方法中使用 Get.put。GetView — 一个简化的 StatelessWidget,通过 controller 访问 Controller,无需 Get.find。
已知限制:GetX 使用全局变量(Get.find、Get.to),可能使测试变得困难。通过 GetX 模拟依赖项需要在测试之间调用 Get.replace() 或 Get.reset()。建议使用 Get.testMode = true 进行隔离。GetX 不推荐用于需要严格架构和清晰层边界的应用程序——在这种情况下,BLoC 或带有代码生成的 Riverpod 更可取。
常见问题
GetX — 拥有自己的 DI、导航和 Rx 响应式的微框架。Provider — 仅通过 ChangeNotifier 和 InheritedWidget 进行状态管理。GetX 不需要 BuildContext,内置导航和 DI,减少 60-70% 的样板代码。Provider 使用标准的 Flutter Navigator,并且需要第三方解决方案进行 DI。GetX 开发更快,Provider — 更接近原生 Flutter API。
Workers — 用于响应式处理 Rx 变量更改的工具。ever — 每次更改时回调,once — 仅第一次,debounce — 带延迟(用于搜索框),interval — 不超过 N 次(用于分析)。Workers 在 onInit() GetxController 中声明,并在 onClose() 中自动取消订阅。这取代了使用 ChangeNotifier 的手动 addListener/removeListener。
GetX 提供 Get.testMode = true 来激活测试模式。依赖项通过 Get.replace<Service>(mockService) 替换。在测试之间调用 Get.reset() 以清除 DI 容器。Controller 可以直接在 Flutter 之外测试:final c = CounterController(); c.increment(); expect(c.count.value, 1)。对于带有 Obx 的 widget,使用带有 InjectMocker 的 tester.pumpWidget。
GetX 适用于任何规模的项目,但需要纪律。对于大型项目(10+ 屏幕),请使用:Bindings 隔离 Controller,模块(按功能的 GetPages 文件),GetView 而不是 build 中的手动 Get.find。主要风险——滥用全局访问(在任何地方使用 Get.find)。严格的代码审查和架构指南解决了这个问题。许多拥有数百万用户的生产应用程序都在 GetX 上运行。
Bindings — 连接路由及其依赖项的类。进入屏幕时,Binding 通过 Get.lazyPut 创建 Controller 和服务,退出时删除它们。Bindings 实现了懒初始化:Controller 在屏幕打开之前不存在于内存中。这节省了 RAM 和应用程序启动时间。在 GetPage 中声明:GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding())。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。