良好的状态管理不仅关注数据流还需要正确处理控制器的初始化、销毁与生命周期事件避免内存泄漏。一、控制器封装Controller1.1 通用控制器基类// 定义通用控制器接口abstractclassBaseController{voidonInit();voidonDispose();}// 带加载/错误状态的控制器基类abstractclassAsyncControllerTextendsChangeNotifier{T?_data;String?_errorMessage;bool _isLoadingfalse;T?getdata_data;String?geterrorMessage_errorMessage;boolgetisLoading_isLoading;boolgethasError_errorMessage!null;boolgethasData_data!null;Futurevoidload()async{_isLoadingtrue;_errorMessagenull;notifyListeners();try{_dataawaitfetchData();}catch(e){_errorMessagee.toString();}finally{_isLoadingfalse;notifyListeners();}}// 子类实现具体数据获取逻辑FutureTfetchData();voidrefresh()load();}1.2 业务控制器实现classProductListControllerextendsAsyncControllerListProduct{finalProductRepository_repository;String_searchQuery;ProductCategory?_selectedCategory;ProductListController(this._repository);StringgetsearchQuery_searchQuery;ProductCategory?getselectedCategory_selectedCategory;overrideFutureListProductfetchData()async{returnawait_repository.fetchProducts(query:_searchQuery,category:_selectedCategory,);}voidupdateSearchQuery(Stringquery){_searchQueryquery;// 防抖延迟500ms再请求_debounce?.cancel();_debounceTimer(constDuration(milliseconds:500),load);}voidfilterByCategory(ProductCategory?category){_selectedCategorycategory;notifyListeners();load();}Timer?_debounce;overridevoiddispose(){_debounce?.cancel();super.dispose();}}二、生命周期事件GetX 风格2.1 GetxController 生命周期classOrderControllerextendsGetxController{finalRxListOrderordersOrder[].obs;StreamSubscription?_orderSubscription;Timer?_pollingTimer;// ① 控制器首次注入时调用类似 initStateoverridevoidonInit(){super.onInit();_loadInitialOrders();_startOrderTracking();_setupEverListeners();}// ② 在 Widget 树中渲染完成后调用overridevoidonReady(){super.onReady();// 适合做需要 UI 就绪后才能执行的操作// 如展示欢迎弹窗}// ③ 控制器销毁时调用类似 disposeoverridevoidonClose(){_orderSubscription?.cancel();_pollingTimer?.cancel();super.onClose();}void_setupEverListeners(){// ever每次变化都触发ever(orders,(_)_updateBadgeCount());// once只触发一次once(orders,(_)_showFirstOrderHint());// debounce防抖debounce(orders,(_)_saveToLocal(),time:constDuration(seconds:1));// interval节流interval(orders,(_)_syncToServer(),time:constDuration(seconds:3));}void_startOrderTracking(){_orderSubscriptionOrderService.orderStream.listen((order)orders.add(order),);}void_loadInitialOrders()async{finaldataawaitOrderRepository.fetchAll();orders.assignAll(data);}void_updateBadgeCount(){// 更新应用角标}}2.2 多控制器协作classCheckoutControllerextendsGetxController{// 依赖其他控制器finalcartControllerGet.findCartController();finaluserControllerGet.findUserController();finalpaymentControllerGet.findPaymentController();finalRxBoolisProcessingfalse.obs;finalRxOrderResult?orderResultRxOrderResult?(null);FuturevoidplaceOrder()async{if(cartController.items.isEmpty){Get.snackbar(提示,购物车为空);return;}isProcessing.valuetrue;try{finalresultawaitOrderService.createOrder(userId:userController.currentUser.value!.id,items:cartController.items,paymentMethod:paymentController.selectedMethod.value,);orderResult.valueresult;cartController.clear();// 清空购物车Get.toNamed(/order-success,arguments:result);}catch(e){Get.snackbar(下单失败,e.toString());}finally{isProcessing.valuefalse;}}}三、Stream 状态同步3.1 Riverpod Stream// 实时监听订单状态riverpodStreamListOrderactiveOrders(ActiveOrdersRefref){finaluserIdref.watch(currentUserProvider).value?.id;if(userIdnull)returnconstStream.empty();// 使用 ref.onDispose 清理资源finalsubscriptionOrderService.watchOrders(userId);ref.onDispose(()subscription.cancel());// ⚠️ 自动清理returnsubscription.stream;}// 在 Widget 中使用Consumer(builder:(context,ref,_){finalordersAsyncref.watch(activeOrdersProvider);returnordersAsync.when(data:(orders)OrderList(orders:orders),loading:()constCircularProgressIndicator(),error:(e,_)Text(Error:$e),);},)3.2 状态同步常见问题// ❌ 问题在已销毁的 State 上调用 setStateclass_MyStateextendsStateMyWidget{Futurevoid_loadData()async{finaldataawaitfetchData();setState(()_datadata);// 如果此时 Widget 已销毁会报错}}// ✅ 解决使用 mounted 检查class_MyStateextendsStateMyWidget{Futurevoid_loadData()async{finaldataawaitfetchData();if(!mounted)return;// ⚠️ 检查是否还在 Widget 树中setState(()_datadata);}}// ✅ 更优使用 Riverpod自动处理生命周期riverpodFutureDataloadData(LoadDataRefref)async{// Riverpod 自动处理取消无需 mounted 检查returnawaitfetchData();}四、生命周期与 Widget 绑定4.1 WidgetsBindingObserver监听应用级生命周期事件class_HomePageStateextendsStateHomePagewithWidgetsBindingObserver{overridevoidinitState(){super.initState();WidgetsBinding.instance.addObserver(this);}overridevoiddispose(){WidgetsBinding.instance.removeObserver(this);super.dispose();}overridevoiddidChangeAppLifecycleState(AppLifecycleStatestate){switch(state){caseAppLifecycleState.resumed:// 应用回到前台刷新数据、恢复播放_refreshData();break;caseAppLifecycleState.paused:// 应用进入后台保存草稿、暂停播放_saveDraft();break;caseAppLifecycleState.detached:// 应用即将关闭break;caseAppLifecycleState.inactive:// 应用非活跃来电、切换等break;caseAppLifecycleState.hidden:// 应用不可见Flutter 3.13break;}}overridevoiddidChangeLocales(ListLocale?locales){// 系统语言变化}overridevoiddidChangePlatformBrightness(){// 系统主题变化深色/浅色}}小结知识点核心要点控制器封装将业务逻辑从 Widget 中分离提高可测试性onInit / onCloseGetX 控制器生命周期替代 initState/disposemounted 检查异步操作后必须检查防止 setState 报错Stream 订阅清理在 dispose 中取消订阅防止内存泄漏WidgetsBindingObserver监听应用前后台切换等系统事件 下一章四、路由与导航