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

Flutter+Firebase启动时网络检测异常问题求助

问题分析

核心问题是启动阶段同步等待网络检测与Firebase初始化,导致UI线程被阻塞,出现白屏卡顿。尤其是网络请求延迟时,InternetAddress.lookup会卡住main函数,直到请求完成才调用runApp,期间App无任何UI输出,表现为白屏。

调试日志里的emuglGLESv2_enc错误是Android模拟器的OpenGL渲染问题,和白屏卡顿无关,可忽略。

解决方案

1. 移除main函数的阻塞逻辑

把网络检测、用户状态判断移到启动页内部异步处理,先完成App初始化,避免阻塞UI加载:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  configureDependencies();
  runApp(const MyApp());
}

2. 用启动页处理异步检测

创建带加载动画的启动页,在后台完成网络与用户状态检测后跳转对应页面:

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

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

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    _checkInitialState();
  }

  Future<void> _checkInitialState() async {
    // 网络检测添加超时,防止无限等待
    bool hasConnection = false;
    try {
      final result = await InternetAddress.lookup('example.com').timeout(
        const Duration(seconds: 3),
        onTimeout: () => [],
      );
      hasConnection = result.isNotEmpty && result[0].rawAddress.isNotEmpty;
    } on SocketException catch (_) {
      hasConnection = false;
    } catch (_) {
      hasConnection = false;
    }

    // 异步获取Firebase用户状态,避免同步值不准确
    final user = await FirebaseAuth.instance.authStateChanges().first;
    final initialRoute = !hasConnection 
        ? '/offlinePage' 
        : (user == null ? '/login' : '/home');

    // 确保页面未被销毁再跳转
    if (mounted) {
      Navigator.pushReplacementNamed(context, initialRoute);
    }
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(child: CircularProgressIndicator()), // 显示加载动画
    );
  }
}

修改MyApp的初始路由为启动页:

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

  @override
  Widget build(BuildContext context) {
    final providers = [EmailAuthProvider()];

    return MaterialApp(
      initialRoute: '/splash',
      routes: {
        '/splash': (context) => const SplashScreen(),
        '/offlinePage': (context) => const OfflinePage(),
        '/login': (context) => const LoginPage(),
        '/home': (context) => const HomePage(),
      },
      // 其他配置...
    );
  }
}

3. 可选:监听网络状态动态切换

如果需要在App运行中响应网络变化,用connectivity_plus包监听状态:

import 'package:connectivity_plus/connectivity_plus.dart';

// 在需要监听的页面添加
late StreamSubscription<ConnectivityResult> _connectivitySubscription;

@override
void initState() {
  super.initState();
  _connectivitySubscription = Connectivity().onConnectivityChanged.listen((result) {
    final hasConnection = result != ConnectivityResult.none;
    // 根据网络状态更新UI或跳转页面
  });
}

@override
void dispose() {
  _connectivitySubscription.cancel();
  super.dispose();
}
关键注意事项
  • 禁止在main函数中执行耗时异步操作,会直接阻塞App启动。
  • 网络检测必须加超时,避免因网络故障卡住流程。
  • Firebase用户状态优先用异步流获取,同步currentUser可能因初始化未完成导致判断错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:34:54