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

Flutter如何一次性实现全应用的网络连接状态全局检测

Flutter 全应用统一互联网连通性检测实现方案

多数零散方案无法全局生效的核心原因有两个:一是监听逻辑写在单个页面生命周期里,页面销毁后监听就失效;二是仅依赖系统返回的网络连接标识判断,没有做真实公网连通性校验,会出现假连接误判。
这套方案仅需一次初始化即可覆盖全应用生命周期,自动同步网络状态、全局兜底无网提示,不需要在单个页面重复写检测逻辑。

1. 引入基础依赖

使用两个轻量包完成基础能力支持:

  • connectivity_plus:监听系统网络类型(WiFi/蜂窝/无连接)的变化
  • internet_connection_checker:发起真实公网请求校验实际连通性,避免假连接误判
    在pubspec.yaml中添加依赖:
dependencies:
  flutter:
    sdk: flutter
  connectivity_plus: ^6.0.3
  internet_connection_checker: ^1.0.0+1

执行flutter pub get完成安装。

2. 实现全局网络状态单例

单例作为整个应用唯一的网络状态数据源,所有页面、组件、业务逻辑都从这里获取网络状态,避免多监听实例冲突。

// 定义全局网络状态枚举
enum GlobalNetStatus { checking, connected, disconnected }

class GlobalNetChecker {
  // 单例构造
  static final GlobalNetChecker _instance = GlobalNetChecker._internal();
  factory GlobalNetChecker() => _instance;
  GlobalNetChecker._internal();

  // 广播流供全应用订阅状态变化
  final StreamController<GlobalNetStatus> _statusController =
      StreamController<GlobalNetStatus>.broadcast();
  Stream<GlobalNetStatus> get statusStream => _statusController.stream;

  // 缓存最新网络状态,支持同步获取
  GlobalNetStatus currentStatus = GlobalNetStatus.checking;
  StreamSubscription? _connectivitySub;

  /// 初始化方法,仅需在应用启动时调用1次
  Future<void> init() async {
    // 启动时先执行一次连通性检测
    await _doRealConnectCheck();
    // 持续监听系统网络变化,变化时自动重新检测
    _connectivitySub = Connectivity().onConnectivityChanged.listen((_) async {
      _statusController.add(GlobalNetStatus.checking);
      await _doRealConnectCheck();
    });
  }

  // 真实连通性校验逻辑
  Future<void> _doRealConnectCheck() async {
    try {
      final hasNet = await InternetConnectionChecker().hasConnection;
      currentStatus = hasNet ? GlobalNetStatus.connected : GlobalNetStatus.disconnected;
    } catch (_) {
      currentStatus = GlobalNetStatus.disconnected;
    }
    _statusController.add(currentStatus);
  }

  /// 供业务层手动触发检测,比如接口请求失败、用户点击重试时调用
  Future<void> manualCheck() async {
    _statusController.add(GlobalNetStatus.checking);
    await _doRealConnectCheck();
  }

  // 应用退出时释放资源
  void dispose() {
    _connectivitySub?.cancel();
    _statusController.close();
  }
}

3. 配置全局无网兜底提示

通过MaterialApp的builder属性注入全局悬浮提示层,不需要在任何页面单独写判断逻辑,所有页面路由下只要断网就会自动弹出提示:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '全局网络检测Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      // 正常配置你的首页、路由表等
      home: const HomePage(),
      // 全局注入网络提示层
      builder: (context, child) {
        return Stack(
          children: [
            child!,
            Positioned(
              top: 0,
              left: 0,
              right: 0,
              child: StreamBuilder<GlobalNetStatus>(
                stream: GlobalNetChecker().statusStream,
                initialData: GlobalNetChecker().currentStatus,
                builder: (context, snapshot) {
                  final status = snapshot.data;
                  // 联网/检测中时不显示提示
                  if (status != GlobalNetStatus.disconnected) {
                    return const SizedBox.shrink();
                  }
                  // 断网时显示顶部提示条,可根据需求改成弹窗、全屏提示等样式
                  return Material(
                    child: Container(
                      padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
                      height: 48 + MediaQuery.of(context).padding.top,
                      color: Colors.redAccent,
                      alignment: Alignment.center,
                      child: const Text(
                        '当前网络不可用,请检查网络连接',
                        style: TextStyle(color: Colors.white, fontSize: 14),
                      ),
                    ),
                  );
                },
              ),
            )
          ],
        );
      },
    );
  }
}

4. 应用入口初始化

在main函数中启动应用前初始化全局检测单例,一次配置全生命周期生效:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 仅需调用这一次初始化
  await GlobalNetChecker().init();
  runApp(const MyApp());
}

可选增强能力

  • 可以在应用生命周期监听、路由跳转拦截中调用manualCheck()方法,避免用户切后台修改网络设置后状态不同步
  • 可以在网络请求框架(比如Dio)的拦截器中读取currentStatus,断网时直接拦截请求返回本地错误,减少无效等待
  • 可以自定义无网提示样式,比如增加点击重试按钮,触发manualCheck()重新检测
  • 业务页面如果需要根据网络状态做差异化逻辑,直接订阅statusStream或者读取currentStatus即可,不需要重复注册系统网络监听

内容的提问来源于stack exchange,提问作者Nisha Jain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:33:20