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

如何在初始化Supabase前检测Flutter应用的网络连接?

针对Flutter网络检测与初始化矛盾的解决方案

直接把网络检测放main开头可行,但要配套容错逻辑

可以在main函数最开头加网络检测,但不能只做检测就直接终止流程——毕竟网络状态可能是临时波动,而且Web和Android的检测方式需要兼容:

  • Android端用connectivity_plus包检测网络类型,Web端可以直接用Navigator.onLine判断(注意Web端这个API只能检测设备是否连上网,无法判断网络是否能访问互联网)
  • 检测后如果无网,不要直接抛出错误退出,而是先启动一个极简的无网提示页,给用户重试或退出的选项;如果有网,再执行后续的Supabase等初始化操作。

示例代码调整:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final aPrefs = await SharedPreferences.getInstance();

  // 先做网络检测
  bool hasNetwork = await checkNetwork();

  if (!hasNetwork) {
    // 无网时先启动提示页
    runApp(
      ProviderScope(
        overrides: [sharedPrefsProvider.overrideWithValue(aPrefs)],
        child: const NoNetworkPage(),
      ),
    );
    return;
  }

  // 有网时执行初始化,加异常捕获处理中途断网情况
  try {
    await SupabaseUtil.init();
    await GdSubscriptionService.init();
  } catch (e) {
    // 初始化失败,跳转错误提示页
    runApp(
      ProviderScope(
        overrides: [sharedPrefsProvider.overrideWithValue(aPrefs)],
        child: const InitFailedPage(),
      ),
    );
    return;
  }

  // 初始化成功,启动主App
  runApp(
    ProviderScope(
      overrides: [sharedPrefsProvider.overrideWithValue(aPrefs)],
      child: const MyApp(),
    ),
  );
}

// 兼容Web和Android的网络检测方法
Future<bool> checkNetwork() async {
  if (kIsWeb) {
    return Navigator.onLine;
  } else {
    final connectivityResult = await Connectivity().checkConnectivity();
    return connectivityResult != ConnectivityResult.none;
  }
}

更优的方案:把初始化移到UI层做,配合全局网络监听

直接在main里做检测的缺点是缺乏灵活的UI反馈(比如加载动画、重试按钮),更合理的做法是:

  • main函数只做必要的本地初始化(比如SharedPreferences),直接启动App
  • 在启动页(SplashScreen)里完成网络检测、Supabase初始化逻辑,同时展示加载状态、无网提示
  • 用connectivity_plus监听网络状态变化,一旦网络恢复,自动触发初始化重试

示例启动页逻辑:

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

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  bool _isLoading = false;
  bool _showError = false;

  @override
  void initState() {
    super.initState();
    _initApp();
    // 监听网络状态变化,恢复时自动重试
    Connectivity().onConnectivityChanged.listen((result) {
      if (result != ConnectivityResult.none && _showError) {
        _initApp();
      }
    });
  }

  Future<void> _initApp() async {
    if (!mounted) return;
    setState(() {
      _isLoading = true;
      _showError = false;
    });
    try {
      await SupabaseUtil.init();
      await GdSubscriptionService.init();
      // 初始化成功,跳转首页
      if (mounted) {
        Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const HomePage()));
      }
    } catch (e) {
      if (mounted) setState(() => _showError = true);
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _isLoading
            ? const CircularProgressIndicator()
            : _showError
                ? Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Text("网络异常,请检查后重试"),
                      const SizedBox(height: 16),
                      ElevatedButton(onPressed: _initApp, child: const Text("重试"))
                    ],
                  )
                : const SizedBox(),
      ),
    );
  }
}

关键注意点

  • 不要依赖单次网络检测:网络状态是动态变化的,必须配合异常捕获和状态监听
  • Web端Navigator.onLine有局限性:如果要判断是否能访问互联网,可以加一个简单的ping请求(比如请求某个可靠的公开API接口)
  • 初始化操作加超时:给Supabase这类依赖网络的初始化设置超时时间,避免长时间卡住

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:42:42