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

Flutter如何实现首页加载时自动检测网络连接?

Flutter 首页自动检测网络状态的问题排查与解决

常见问题原因

  • 异步操作未触发UI更新:initState中调用Connectivity.checkConnectivity()是异步方法,直接调用后如果不执行setState,UI不会刷新
  • Stream订阅未持久化:onConnectivityChanged返回的StreamSubscription如果是局部变量,会在initState执行完后被GC回收,无法持续监听状态变化
  • 混淆连接状态与真实联网:Connectivity插件仅检测设备是否连接到网络(如WiFi/蜂窝),不验证是否能访问互联网,若你需要的是真实连通性,得结合InternetConnectionChecker

改进实现方案

1. 准备依赖

确保pubspec.yaml中添加了所需依赖:

dependencies:
  flutter:
    sdk: flutter
  connectivity_plus: ^5.0.1  # 推荐用维护更活跃的connectivity_plus替代原Connectivity
  internet_connection_checker: ^1.0.0+1

2. 完整代码实现

import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _networkStatus = "检测中...";
  // 保存订阅对象,避免被GC回收
  StreamSubscription? _connectivitySubscription;
  StreamSubscription? _internetSubscription;

  @override
  void initState() {
    super.initState();
    // 进入页面立即检测网络
    _checkNetworkStatus();
    // 启动状态监听
    _startNetworkListening();
  }

  @override
  void dispose() {
    // 页面销毁时取消订阅,防止内存泄漏
    _connectivitySubscription?.cancel();
    _internetSubscription?.cancel();
    super.dispose();
  }

  // 同时检测网络连接类型与真实联网状态
  Future<void> _checkNetworkStatus() async {
    // 获取设备连接的网络类型
    final connectivityResult = await Connectivity().checkConnectivity();
    String connectionType;
    switch (connectivityResult) {
      case ConnectivityResult.wifi:
        connectionType = "WiFi";
        break;
      case ConnectivityResult.mobile:
        connectionType = "移动网络";
        break;
      case ConnectivityResult.none:
        connectionType = "无网络";
        break;
      default:
        connectionType = "未知";
    }

    // 检测是否能访问互联网
    final hasInternet = await InternetConnectionChecker().hasConnection;
    String internetTip = hasInternet ? "(可正常联网)" : "(无法访问互联网)";

    // 更新UI
    setState(() {
      _networkStatus = "$connectionType $internetTip";
    });
  }

  // 监听网络状态变化
  void _startNetworkListening() {
    // 监听连接类型变化
    _connectivitySubscription = Connectivity().onConnectivityChanged.listen((_) {
      // 连接类型变化时重新检测完整状态
      _checkNetworkStatus();
    });

    // 可选:直接监听真实联网状态的实时变化
    _internetSubscription = InternetConnectionChecker().onStatusChange.listen((status) {
      final isConnected = status == InternetConnectionStatus.connected;
      setState(() {
        if (_networkStatus.contains("WiFi") || _networkStatus.contains("移动网络")) {
          _networkStatus = _networkStatus.replaceRange(
            _networkStatus.indexOf("("),
            null,
            isConnected ? "(可正常联网)" : "(无法访问互联网)"
          );
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("网络检测")),
      body: Center(
        child: Text(_networkStatus, style: const TextStyle(fontSize: 18)),
      ),
    );
  }
}

3. 关键改进点

  • 持久化Stream订阅:将StreamSubscription保存为类成员,在dispose中取消订阅,避免内存泄漏和订阅被回收
  • 异步操作绑定UI更新:在异步检测完成后调用setState,确保网络状态能实时反映到UI上
  • 区分连接状态与真实联网:结合两款插件,既展示用户连接的网络类型,又验证是否能正常访问互联网
  • 初始化主动触发检测:initState中直接调用检测方法,确保进入首页时立即执行网络检测

权限配置提醒

  • Android:在AndroidManifest.xml中添加权限
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    
  • iOS:在Info.plist中添加配置
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    

内容的提问来源于stack exchange,提问作者Arjun Malhotra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:20:36