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

Flutter使用connectivity_plus检测网络始终返回在线问题排查

问题修复方案

核心根因

你遇到的问题核心是InternetAddress.lookup会读取系统DNS缓存,就算设备已经断网,只要之前的DNS解析记录还在缓存有效期内,就会返回成功结果,导致isOnline一直为true。另外你的代码还存在初始化未主动检测网络、部分场景权限缺失的问题,完整修复步骤如下:

修复步骤

    1. 替换DNS查询逻辑为socket连接检测,规避DNS缓存问题
    1. 新增初始化网络状态检测逻辑,避免应用刚启动时状态错误
    1. 补充必要的平台权限,适配Android平台
    1. 优化变量命名,避免参数与内部变量名冲突导致的逻辑歧义

完整修复代码

connectivity_check.dart

import 'dart:async';
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';

enum ConnectivityStatus { Online, Offline }

class ConnectivityService {
  StreamController<ConnectivityStatus> connectionStatusController =
      StreamController<ConnectivityStatus>();
  final _connectivity = Connectivity();
  ConnectivityService() {
    // 初始化主动检测一次当前网络状态
    _initStatusCheck();
    // 监听网络变化事件
    _connectivity.onConnectivityChanged.listen((ConnectivityResult result) {
      _checkConnectivityStatus(result);
    });
  }

  Future<void> _initStatusCheck() async {
    final currentConnectivity = await _connectivity.checkConnectivity();
    _checkConnectivityStatus(currentConnectivity);
  }

  void _checkConnectivityStatus(ConnectivityResult connectivityResult) async {
    bool isOnline = false;
    // 无网络连接时直接返回离线,减少无效请求
    if (connectivityResult == ConnectivityResult.none) {
      isOnline = false;
    } else {
      try {
        // 用socket连接公共DNS服务器检测真实连通性,规避DNS缓存问题
        // 国内用户可替换为 114.114.114.114 端口53,延迟更低
        final socket = await Socket.connect(
          '8.8.8.8',
          53,
          timeout: const Duration(seconds: 3),
        );
        socket.destroy();
        isOnline = true;
      } on SocketException catch (_) {
        isOnline = false;
      } catch (_) {
        isOnline = false;
      }
    }
    connectionStatusController.sink.add(
      isOnline ? ConnectivityStatus.Online : ConnectivityStatus.Offline
    );
  }

  void disposeStream() => connectionStatusController.close();
}

Android权限配置

在android/app/src/main/AndroidManifest.xml的manifest标签下添加两个权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

调试建议

  • 在_checkConnectivityStatus方法中打印connectivityResult和isOnline的取值,确认每一步逻辑输出符合预期
  • 优先使用真机测试,模拟器的网络状态模拟常出现状态不更新的问题
  • 测试时切换网络状态后等待1-3秒,等待socket检测超时返回结果

内容的提问来源于stack exchange,提问作者Rishabh Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 02:18:03