GetX:关键概念,Flutter 导航与 DI

作者: IT Sectr 发布日期: 2026-02-19 阅读时间: 7 分钟

GetX — 一个轻量级的 Flutter 微框架,将状态管理、导航和依赖注入整合在一个包中。由 Amir Hossein Abdorashidi 开发,GetX 提供最少的样板代码:无需 Stream、无需 ChangeNotifier、无需 BuildContext 即可导航。根据 pub.dev 的数据,GetX 已获得超过 1.3 万个赞,成为最受欢迎的 Flutter 包之一。

要点

  • Obx — 在 Rx 变量更改时重建的响应式 widget
  • GetController — 包含方法和 Rx 变量的业务逻辑类
  • Get.to — 通过命名路由无需 BuildContext 进行导航
  • Get.put / Get.find — 通过 DI 容器注入和获取依赖
  • Rx 变量 — 带自动通知的响应式包装器(RxInt、RxString、RxBool)

什么是 GetX?

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 和 Rx

Obx — GetX 的响应式 widget,当 Rx 变量更改时重建。Obx 不需要订阅、dispose 或 Builder 函数——只需将 widget 包装在 Obx 中并在内部使用 Rx 变量即可。Obx 自动跟踪使用了哪些 Rx 变量,并且仅在它们更改时重绘。

Dart
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 类:RxIntRxStringRxDoubleRxBoolRxListRxMap。所有 Rx 变量都像普通原语一样行为:count++name.value = 'Hello'items.add(item)。更改会自动通知 Obx 订阅者。

GetBuilder — 无 Rx 的 Obx 替代方案,通过手动调用 update() 工作。GetBuilder.filter — 根据 ID 键进行定点更新。Obx 更快(自动依赖跟踪),GetBuilder 更可预测(显式更新调用)。建议简单场景使用 Obx,复杂 widget 使用 GetBuilder。

GetController 和生命周期

GetxController — 支持生命周期的业务逻辑基类。GetxController 有以下方法:onInit()(初始化)、onReady()(第一帧后)、onClose()(清理资源)。与 ChangeNotifier 和 StateNotifier 不同,GetxController 自动管理订阅:当页面销毁时,所有 Rx 变量和 Workers 都会取消订阅。

Dart
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 的参数传递。

Dart
// 普通导航
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 仅在屏幕打开时创建。

使用 GetX 进行依赖注入

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.putAsyncFuture 执行后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:最佳实践和性能

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 与 Provider 有什么不同?

GetX — 拥有自己的 DI、导航和 Rx 响应式的微框架。Provider — 仅通过 ChangeNotifier 和 InheritedWidget 进行状态管理。GetX 不需要 BuildContext,内置导航和 DI,减少 60-70% 的样板代码。Provider 使用标准的 Flutter Navigator,并且需要第三方解决方案进行 DI。GetX 开发更快,Provider — 更接近原生 Flutter API。

什么是 GetX Workers?

Workers — 用于响应式处理 Rx 变量更改的工具。ever — 每次更改时回调,once — 仅第一次,debounce — 带延迟(用于搜索框),interval — 不超过 N 次(用于分析)。Workers 在 onInit() GetxController 中声明,并在 onClose() 中自动取消订阅。这取代了使用 ChangeNotifier 的手动 addListener/removeListener。

如何测试 GetX?

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 吗?

GetX 适用于任何规模的项目,但需要纪律。对于大型项目(10+ 屏幕),请使用:Bindings 隔离 Controller,模块(按功能的 GetPages 文件),GetView 而不是 build 中的手动 Get.find。主要风险——滥用全局访问(在任何地方使用 Get.find)。严格的代码审查和架构指南解决了这个问题。许多拥有数百万用户的生产应用程序都在 GetX 上运行。

什么是 GetX Bindings?

Bindings — 连接路由及其依赖项的类。进入屏幕时,Binding 通过 Get.lazyPut 创建 Controller 和服务,退出时删除它们。Bindings 实现了懒初始化:Controller 在屏幕打开之前不存在于内存中。这节省了 RAM 和应用程序启动时间。在 GetPage 中声明:GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding())

总结

  • GetX — 集状态管理、导航和 DI 于一体的 Flutter 微框架
  • Obx 和 Rx — 无需 Stream 和 ChangeNotifier 即可自动重绘的响应式包装器
  • GetxController — 具有 onInit/onReady/onClose 生命周期的业务逻辑类
  • Get.to / Get.back — 无需 BuildContext 且内置动画的导航
  • Get.put / Get.find — 无需 Provider 树且支持懒初始化的 DI 容器
  • Workers — ever、once、debounce、interval,用于响应式处理更改
  • Bindings — 打开路由时对 Controller 进行懒初始化并自动销毁

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读