Riverpod中StateNotifier仅返回初始状态,网络状态不更新求助
问题描述
在Flutter中使用Riverpod实现全应用网络连通性检测,但StateNotifier始终仅返回初始的false状态,网络状态变更时无法更新。无论网络是否连通,输出始终为false,尝试过connectivity_plus包及相关教程方案均未解决。
原代码如下:
InternetProvider.dart
import 'package:internet_connection_checker_plus/internet_connection_checker_plus.dart'; import 'package:riverpod/riverpod.dart'; class ConnectivityStatusNotifier extends StateNotifier<bool> { ConnectivityStatusNotifier() : super(false); void checkInternet() { final listener = InternetConnection().onStatusChange.listen((InternetStatus status) { if (status == InternetStatus.connected) { state = true; } else{ state = false; } }); } } final connectivityProvider = StateNotifierProvider<ConnectivityStatusNotifier, bool>((ref) { return ConnectivityStatusNotifier(); });
HomeScreen.dart
final internet = ref.watch(connectivityProvider); final Widget floatingActionButton = FloatingActionButton( onPressed: () { print(internet); }, child: const Icon(Icons.chat), );
问题原因
- 监听未启动:
checkInternet方法从未被调用,导致InternetConnection的状态监听没有开始,state始终保持初始的false。 - 未管理Stream订阅:即使调用了
checkInternet,生成的Stream订阅没有被保存和取消,会造成内存泄漏。
解决方案
修正InternetProvider.dart
让StateNotifier在构造函数中自动启动监听,并管理Stream订阅的生命周期:
import 'package:internet_connection_checker_plus/internet_connection_checker_plus.dart'; import 'package:riverpod/riverpod.dart'; class ConnectivityStatusNotifier extends StateNotifier<bool> { late final StreamSubscription<InternetStatus> _subscription; ConnectivityStatusNotifier() : super(false) { // 初始化时立即启动网络状态监听 _initConnectivityListener(); } void _initConnectivityListener() { _subscription = InternetConnection().onStatusChange.listen((status) { state = status == InternetStatus.connected; }); } @override void dispose() { // 销毁时取消订阅,避免内存泄漏 _subscription.cancel(); super.dispose(); } } final connectivityProvider = StateNotifierProvider<ConnectivityStatusNotifier, bool>((ref) { final notifier = ConnectivityStatusNotifier(); return notifier; });
修正HomeScreen.dart
确保在Widget的build方法内使用ref.watch,这样状态更新时会触发UI重建,获取最新的网络状态:
@override Widget build(BuildContext context, WidgetRef ref) { // 在build方法内监听状态,确保状态更新时能拿到最新值 final internet = ref.watch(connectivityProvider); return Scaffold( floatingActionButton: FloatingActionButton( onPressed: () { print(internet); }, child: const Icon(Icons.chat), ), // 其他UI代码... ); }
额外说明
如果需要主动触发一次网络检测(而非仅监听状态变化),可以在Notifier中添加方法手动调用InternetConnection().hasInternetAccess并更新state:
Future<void> checkConnectionManually() async { final hasConnection = await InternetConnection().hasInternetAccess; state = hasConnection; }
然后在需要的地方通过ref.read(connectivityProvider.notifier).checkConnectionManually()调用。
内容的提问来源于stack exchange,提问作者Musab Shaikh
相关产品推荐
相关产品推荐

