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

Flutter应用切后台再打开后无网络警告无法消失问题求助

问题原因分析
  1. 状态重置导致逻辑失效:firstCheck在StatelessWidget的build方法中被每次重置为-1,应用从后台返回触发组件重建时,即使网络正常,也会因firstCheck!=-1条件不满足,无法将isConnectedToInternet更新为1,而之前的无网络状态值2会被保留,导致警告持续显示。
  2. BottomSheet设计不匹配需求:BottomSheet默认是需用户主动关闭的持久化组件,用SizedBox隐藏的方式不可靠,且空实现onClosing会导致组件状态异常。

修复方案

将MyApp改为StatefulWidget,把状态变量移到内部管理,同时优化网络状态更新逻辑:

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final ValueNotifier<int> _isConnectedToInternet = ValueNotifier(-1);
  int _firstCheck = -1;

  @override
  Widget build(BuildContext context) {
    ScreenSize.init(context);
    return InternetConnectivityListener(
      connectivityListener: (BuildContext context, bool hasInternetAccess) {
        if (hasInternetAccess) {
          // 仅当网络从断开恢复时,显示连接成功提示
          if (_isConnectedToInternet.value == 2) {
            showToast(
              'Connected to Internet',
              backgroundColor: Colors.green,
              textColor: Colors.white
            );
          }
          _isConnectedToInternet.value = 1;
          _firstCheck = 0;
        } else {
          _isConnectedToInternet.value = 2;
          _firstCheck = 0;
        }
      },
      child: MultiProvider(
        providers: [ChangeNotifierProvider(create: (_) => MainProvider())],
        child: MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: myCustomTheme,
          scaffoldMessengerKey: scaffoldMessengerKey,
          navigatorKey: navigatorKey,
          initialRoute: MyRoute.splashScreen,
          onGenerateRoute: RouteGenerator.generateRoute,
          builder: (context, child) {
            return Scaffold(
              body: Stack(
                children: [
                  child!,
                  // 自定义底部提示组件,替代BottomSheet
                  ValueListenableBuilder(
                    valueListenable: _isConnectedToInternet,
                    builder: (context, isConnected, child) {
                      if (isConnected == 2) {
                        return const Positioned(
                          bottom: 0,
                          left: 0,
                          right: 0,
                          child: NoInternetConnectionWarning(),
                        );
                      }
                      return const SizedBox.shrink();
                    },
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

优化建议

1. 改用Snackbar实现自动消失提示

Snackbar更符合“临时提示”的场景,无需手动维护BottomSheet状态:

// 在connectivityListener中替换原有逻辑
if (hasInternetAccess) {
  // 关闭无网络提示,仅当之前显示过
  ScaffoldMessenger.of(context).hideCurrentSnackBar();
  // 仅从断开恢复时显示成功提示
  if (_isConnectedToInternet.value == 2) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('Connected to Internet'),
        backgroundColor: Colors.green,
        duration: Duration(seconds: 3),
      ),
    );
  }
  _isConnectedToInternet.value = 1;
} else {
  // 显示无网络提示,持续到网络恢复
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(
      content: const Text('No Internet Connection'),
      backgroundColor: Colors.red,
      duration: const Duration(days: 1),
      action: SnackBarAction(
        label: 'Close',
        onPressed: () => ScaffoldMessenger.of(context).hideCurrentSnackBar(),
      ),
    ),
  );
  _isConnectedToInternet.value = 2;
}

2. 状态管理优化

将网络状态逻辑抽离到单独的ChangeNotifier中,避免在Widget中维护状态:

class NetworkProvider extends ChangeNotifier {
  bool _hasInternet = false;
  bool get hasInternet => _hasInternet;

  void updateStatus(bool status) {
    if (_hasInternet != status) {
      _hasInternet = status;
      notifyListeners();
    }
  }
}

在InternetConnectivityListener中调用NetworkProvider的方法更新状态,再通过Consumer组件监听状态变化显示提示。

3. 避免重复提示

通过记录上一次网络状态,仅在状态切换时触发提示,避免应用前后台切换时重复弹出提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:33:38