flutter_offline在iOS中网络连接检测不准确问题排查求助
问题分析与解决方案
核心问题
- iOS网络检测特性:flutter_offline依赖的底层网络检测插件在iOS上,网络状态切换过程中会频繁触发多次回调(比如Wi-Fi切换蜂窝网络时,会短暂出现
ConnectivityResult.none状态),导致你的代码重复执行弹窗逻辑。 - 无重复弹窗控制:每次检测到无网络状态就直接调用
showDialog,没有判断当前是否已显示弹窗,导致多次弹出。 - 错误的弹窗时机:在
connectivityBuilder中直接通过addPostFrameCallback弹框,而该回调会随网络状态变化多次执行,未结合状态管理控制弹窗显示逻辑。
修复方案
- 新增弹窗状态变量,跟踪弹窗是否已显示,避免重复触发。
- 添加短暂延迟过滤iOS瞬时网络波动,确保仅持续无网络状态才弹框。
- 将
MyApp改为StatefulWidget,用于管理弹窗状态。
修改后的代码
class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { // 跟踪无网络弹窗是否已显示 bool _isNoInternetDialogShown = false; @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: Scaffold( body: OfflineBuilder( connectivityBuilder: ( BuildContext context, ConnectivityResult connectivity, Widget child, ) { final bool connected = connectivity != ConnectivityResult.none; if (connected) { // 联网时关闭弹窗并重置状态 if (_isNoInternetDialogShown) { Navigator.of(context).pop(); setState(() => _isNoInternetDialogShown = false); } return child; } else { // 仅在弹窗未显示时触发弹框逻辑 if (!_isNoInternetDialogShown) { setState(() => _isNoInternetDialogShown = true); // 延迟500ms过滤瞬时网络波动 Future.delayed(const Duration(milliseconds: 500), () { if (connectivity == ConnectivityResult.none && _isNoInternetDialogShown) { showDialog( context: context, barrierDismissible: false, // 禁止手动关闭,联网后自动关闭 builder: (context) { return const AlertDialog( title: Text('无网络'), content: Text('你当前未连接到互联网'), ); }, ).then((_) => setState(() => _isNoInternetDialogShown = false)); } }); print('无网络'); } } return child; }, errorBuilder: (context) => const Center(child: Text("错误")), child: const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('已连接到互联网'), ], ), ), ), ), ); } }
关键优化点说明
_isNoInternetDialogShown变量严格控制弹窗的显示状态,避免重复弹出。Future.delayed过滤iOS上的瞬时网络状态变化,防止误判。- 联网时自动关闭弹窗并重置状态,提升用户体验。
- 设置
barrierDismissible: false,避免用户手动关闭弹窗后,网络未恢复时再次重复弹出。
内容的提问来源于stack exchange,提问作者Yassine BENNKHAY
相关产品推荐
相关产品推荐

