Flutter:解决在WidgetsBindingObserver中调用Riverpod Provider的问题
解决方法
你的核心问题是:ref是build方法的局部参数,类的didChangeAppLifecycleState方法无法直接访问它;另外你在build里每次调用WidgetsBinding.instance.addObserver(this)会重复注册观察者,导致回调被多次触发,这也需要修复。
下面给你两种可行的解决方案:
方案一:改用ConsumerStatefulWidget,在State类中管理ref与观察者
把无状态的ConsumerWidget换成有状态的ConsumerStatefulWidget,在initState里仅注册一次观察者,dispose里移除观察者,同时State类可以直接访问ref,完美解决生命周期方法中调用Provider的问题:
final homePageProvider = ChangeNotifierProvider((ref) => HomePageState()); class HomePageState extends ChangeNotifier { bool _something = false; // 修正你原代码的getter错误:返回_something而非不存在的_isEmailVerified bool get something => _something; void setSomething(bool value) { _something = value; notifyListeners(); } } class NewHome extends ConsumerStatefulWidget { const NewHome({super.key}); @override ConsumerState<NewHome> createState() => _NewHomeState(); } class _NewHomeState extends ConsumerState<NewHome> with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); // 仅注册一次观察者 } @override void dispose() { WidgetsBinding.instance.removeObserver(this); // 销毁时移除,避免内存泄漏 super.dispose(); } @override Widget build(BuildContext context) { final homeState = ref.watch(homePageProvider); return Scaffold( // 替换成你的实际UI代码 body: Center(child: Text(homeState.something ? "已设置" : "未设置")), ); } @override void didChangeAppLifecycleState(AppLifecycleState state) { switch (state) { case AppLifecycleState.resumed: if (someCondition == false) { // 替换成你实际的判断条件 ref.read(homePageProvider).setSomething(true); } break; case AppLifecycleState.paused: case AppLifecycleState.detached: case AppLifecycleState.inactive: case AppLifecycleState.hidden: break; } } }
方案二:在build方法中保存ref到类成员(不推荐,存在泄漏风险)
如果你不想改成有状态组件,可以在build里把ref赋值给类的成员变量,但要注意避免重复注册观察者,同时因为ConsumerWidget没有dispose方法,观察者无法被移除,存在内存泄漏风险:
final homePageProvider = ChangeNotifierProvider((ref) => HomePageState()); class HomePageState extends ChangeNotifier { bool _something = false; bool get something => _something; void setSomething(bool value) { _something = value; notifyListeners(); } } class NewHome extends ConsumerWidget with WidgetsBindingObserver{ WidgetRef? _ref; @override Widget build(BuildContext context, WidgetRef ref) { _ref = ref; // 仅在未注册时添加观察者,避免重复注册 if (!WidgetsBinding.instance.isObserverRegistered(this)) { WidgetsBinding.instance.addObserver(this); } final homeState = ref.watch(homePageProvider); return Scaffold( body: Center(child: Text(homeState.something ? "已设置" : "未设置")), ); } @override void didChangeAppLifecycleState(AppLifecycleState state) { final ref = _ref; if (ref == null) return; // 防止ref未初始化的情况 switch (state) { case AppLifecycleState.resumed: if (someCondition == false) { ref.read(homePageProvider).setSomething(true); } break; default: break; } } }
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

