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
相关产品推荐
相关产品推荐

