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

如何通过路由全局检查Flutter应用的网络连接状态

实现Flutter全局网络连接检查方案

你的方案无效的核心原因是:onGenerateRoute在build时初始化,传入的_connectionStatus是当时的静态值,后续网络状态变化时,不会触发onGenerateRoute更新,导致路由跳转无法获取最新网络状态。以下是基于你现有代码(使用Consumer)的可行方案:

1. 用Riverpod管理全局网络状态

将网络状态从Widget的State中剥离,用全局状态管理统一维护,确保任何地方都能获取最新状态:

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:developer' as developer;

final connectivityProvider = StateNotifierProvider<ConnectivityNotifier, ConnectivityResult>(
  (ref) => ConnectivityNotifier(),
);

class ConnectivityNotifier extends StateNotifier<ConnectivityResult> {
  final Connectivity _connectivity = Connectivity();
  late StreamSubscription<ConnectivityResult> _subscription;

  ConnectivityNotifier() : super(ConnectivityResult.none) {
    _initConnectivity();
    _subscription = _connectivity.onConnectivityChanged.listen((result) {
      state = result;
    });
  }

  Future<void> _initConnectivity() async {
    try {
      final result = await _connectivity.checkConnectivity();
      state = result;
    } on PlatformException catch (e) {
      developer.log('无法检查网络状态', error: e);
    }
  }

  @override
  void dispose() {
    _subscription.cancel();
    super.dispose();
  }
}

2. 修改App入口,让路由生成读取最新状态

将原ConsumerStatefulWidget改为ConsumerWidget,在onGenerateRoute中传入WidgetRef,直接读取最新网络状态:

class MyProjectAppScreen extends ConsumerWidget {
  const MyProjectAppScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    const String appRoot = splash;
    return MaterialApp(
      title: 'My Project',
      theme: theme_data.ManageTheme().getTheme(context),
      darkTheme: theme_data.ManageTheme().getDarkTheme(context),
      themeMode: ThemeMode.light,
      initialRoute: appRoot,
      onGenerateRoute: (settings) => generateRoute(settings, ref),
      debugShowCheckedModeBanner: false,
    );
  }
}

3. 重写路由生成逻辑,加入网络检查

在generateRoute中实时读取网络状态,动态跳转页面:

Route<dynamic> generateRoute(RouteSettings settings, WidgetRef ref) {
  final connectivityStatus = ref.watch(connectivityProvider);

  // 无网络时,统一跳转到无网络页面(排除无网络页面自身)
  if (connectivityStatus == ConnectivityResult.none) {
    if (settings.name != '/no-internet') {
      return MaterialPageRoute(
        builder: (context) => const NoInternetScreen(),
        settings: const RouteSettings(name: '/no-internet'),
      );
    }
  } else {
    // 网络正常时,按原有逻辑跳转目标页面
    switch (settings.name) {
      case splash:
        return MaterialPageRoute(builder: (context) => const SplashScreen());
      // 添加你的其他路由 case
      default:
        return MaterialPageRoute(builder: (context) => const NotFoundScreen());
    }
  }

  return MaterialPageRoute(builder: (context) => const NoInternetScreen());
}

4. 实现无网络页面,处理网络恢复跳转

在无网络页面中监听网络状态,恢复时自动跳转回原页面:

class NoInternetScreen extends ConsumerStatefulWidget {
  const NoInternetScreen({super.key});

  @override
  ConsumerState<NoInternetScreen> createState() => _NoInternetScreenState();
}

class _NoInternetScreenState extends ConsumerState<NoInternetScreen> {
  @override
  void initState() {
    super.initState();
    // 监听网络状态变化,恢复时返回首页或原页面
    ref.listen<ConnectivityResult>(connectivityProvider, (previous, next) {
      if (next != ConnectivityResult.none) {
        Navigator.popUntil(context, (route) => route.isFirst);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('无网络连接,请检查网络设置'),
            ElevatedButton(
              onPressed: () {
                // 手动触发网络重新检查
                ref.read(connectivityProvider.notifier)._initConnectivity();
              },
              child: const Text('重试'),
            ),
          ],
        ),
      ),
    );
  }
}

补充说明

  • 如果需要验证真实互联网可达性(而非仅连接状态),可以在_initConnectivity中加入HTTP请求验证(比如请求一个稳定的公共接口),更新状态时结合连接状态和请求结果。
  • 确保在项目中已添加connectivity_plus依赖,并配置好平台权限(比如Android的ACCESS_NETWORK_STATE,iOS的NSAppTransportSecurity)。

内容的提问来源于stack exchange,提问作者Gaurav Khatri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 12:51:11