Flutter项目SplashScreen启动延迟、部分设备出现黑白屏问题如何解决?
Flutter SplashScreen启动慢/白屏问题修复方案
你遇到的两个问题本质是Flutter引擎初始化前原生层占位缺失、Dart层启动页绘制逻辑冗余导致,可按以下步骤修复:
先修复现有代码的明显错误
你贴出的代码第一行多了多余字符,enimport需要修改为import,否则会触发编译报错。
1 修复登录操作完成后SplashScreen打开延迟
- 移除build方法内的runtime判断:将
IsSplashOnlySolidColor的布局判断提前到初始化阶段,不要在绘制周期执行逻辑,减少绘制耗时 - 预加载图片资源:在登录页执行登录成功逻辑前,提前预加载启动页用到的logo资源,避免跳转时才加载图片导致卡顿
// 登录页跳转前执行预加载 precacheImage(const AssetImage('assets/images/logo.png'), context);
- 优化跳转逻辑:登录完成后跳转启动页时使用
Navigator.pushReplacement代替普通push,减少页面栈冗余,跳转时不要叠加自定义过渡动画,用系统默认动画即可
2 修复设备启动时白屏/黑屏问题
这个问题的核心是Dart层的SplashScreen要等Flutter引擎初始化完成后才会渲染,引擎初始化的空白期没有原生层占位就会出现白/黑屏,需要给双端添加原生启动页:
- Android端配置:在
android/app/src/main/res/drawable/launch_background.xml中配置和你Dart层启动页一致的背景、logo资源,示例如下:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/holo_blue_dark" /> <item> <bitmap android:gravity="center" android:src="@mipmap/launcher_logo" /> </item> </layer-list>
然后在AndroidManifest.xml的MainActivity节点的theme属性中引用该启动背景配置即可
- iOS端配置:打开Xcode项目,在
Runner/Assets.xcassets中新建LaunchImage图片集,放入对应分辨率的启动图,然后在项目General选项卡的Launch Screen File项选择对应的启动页配置即可 - 额外优化:不要在SplashScreen的
initState中执行任何耗时初始化逻辑,权限申请、第三方SDK初始化、埋点上报等操作放到首页渲染完成后延迟执行,不要抢占引擎初始化资源
优化后可直接使用的Dart层SplashScreen代码
import 'package:cms/Configs/app_constants.dart'; import 'package:flutter/material.dart'; class Splashscreen extends StatefulWidget { @override _Splashscreen createState() => _Splashscreen(); } class _Splashscreen extends State<Splashscreen> { // 提前初始化布局,避免build阶段重复计算 final Widget _splashBody = IsSplashOnlySolidColor == true ? const Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)), ) : Center( child: Image.asset( 'assets/images/logo.png', fit: BoxFit.cover, ), ); @override void initState() { super.initState(); // 仅在initState执行最少的跳转逻辑 Future.delayed(const Duration(milliseconds: 1500), () { // 此处添加跳转到首页/登录页的逻辑 }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.blue, body: _splashBody, ); } }
内容的提问来源于stack exchange,提问作者UDAY KOL
相关产品推荐
相关产品推荐

