You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

flutter_offline在iOS中网络连接检测不准确问题排查求助

问题分析与解决方案

核心问题

  • iOS网络检测特性:flutter_offline依赖的底层网络检测插件在iOS上,网络状态切换过程中会频繁触发多次回调(比如Wi-Fi切换蜂窝网络时,会短暂出现ConnectivityResult.none状态),导致你的代码重复执行弹窗逻辑。
  • 无重复弹窗控制:每次检测到无网络状态就直接调用showDialog,没有判断当前是否已显示弹窗,导致多次弹出。
  • 错误的弹窗时机:在connectivityBuilder中直接通过addPostFrameCallback弹框,而该回调会随网络状态变化多次执行,未结合状态管理控制弹窗显示逻辑。

修复方案

  1. 新增弹窗状态变量,跟踪弹窗是否已显示,避免重复触发。
  2. 添加短暂延迟过滤iOS瞬时网络波动,确保仅持续无网络状态才弹框。
  3. 将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 02:58:22