当前位置: 首页 > news >正文

为什么 Android App 启动会白一下?——一篇讲透 Android SplashScreen 启动机制演进

一、前言:一次面试,把我问懵了

前段时间面试时,面试官突然问了我一个问题:

“Android App 为什么启动时会白一下?”

紧接着又问:

“为什么 Android12 后官方不推荐 SplashActivity?”

一开始我以为只是:

windowBackground 没配好

的问题。

但后来深入研究后才发现:

这背后其实涉及:

Android 启动机制 + Window Preview + Starting Window + Android12 SplashScreen + Framework 启动链路演进

这一整套东西。

这一篇文章,我们就彻底把:Android Splash 启动机制讲透。

二、老 Android 的启动方式(Android11 及以下)

以前绝大部分 Android 项目:

都是这样写启动页的:

Launcher ↓ SplashActivity ↓ MainActivity

经典代码:

Handler(Looper.getMainLooper()).postDelayed({ startActivity( Intent(this, MainActivity::class.java) ) finish() }, 2000)

也就是:

启动页停留2秒 再跳首页

那个年代:

SplashActivity ≈ 启动页本身

三、为什么以前感觉“没有系统 Splash”?

很多老 Android 开发都会有一个感觉:

以前明明没有系统 Splash 为什么现在突然多了一层?

其实:

以前并不是完全没有。

只是以前的机制是:

Window Preview

系统启动 Activity 时:

  1. 实际上会先创建一个:Starting Window
  2. 然后显示:android:windowBackground

所以以前真实流程其实是:

Launcher ↓ 创建Window ↓ 显示windowBackground ↓ SplashActivity绘制 ↓ 真正页面显示

但因为:

windowBackground

通常会被配置成:

  • 启动背景图
  • 品牌色
  • Logo背景

于是:

Window Preview 和 SplashActivity 视觉一致

所以肉眼感觉:

“一打开就是 Splash”

四、白屏到底是怎么产生的?

现在终于进入核心问题。

很多人以为:

白屏 = 页面加载慢

其实不完全对。

白屏真正发生的位置:

Activity 真正绘制之前

系统流程:

点击App ↓ AMS/ATMS启动Activity ↓ 创建Window ↓ 显示windowBackground ↓ Activity开始绘制 ↓ setContentView / Compose ↓ 真正页面显示

所以:

白屏本质: 是 Starting Window 阶段的背景色问题

如果:

android:windowBackground

没有配置。

系统默认:通常就是白色。

于是:

用户看到: 白一下

五、Android12(API31)到底改变了什么?

真正的变化 发生在:

Android12(API31)

Google 正式引入:

SplashScreen API

从此:

系统开始强制接管启动第一页

启动流程变成:

Launcher ↓ System SplashScreen ↓ 你的Activity

注意:

这里已经不是以前简单的:

windowBackground Preview

而是:

真正的系统 SplashScreen

也就是说:

Android12+ 系统自己也有启动页了

六、为什么 Android12 后容易出现“双 Splash”?

很多老项目升级后:

都会出现:

系统 Splash ↓ 自己写的 SplashActivity ↓ MainActivity

于是:

  • 白一下
  • 双启动页
  • Logo不一致
  • 页面闪烁

问题全来了。

这也是为什么:

Google 官方开始不推荐:

SplashActivity + 延迟跳转

这种老方案。


七、Theme.SplashScreen 是什么?

Android12 后 Google 提供了:

Theme.SplashScreen

例如:

<style name="Theme.App.Starting" parent="Theme.SplashScreen"> <!-- 背景 --> <item name="windowSplashScreenBackground"> @color/splash_bg </item> <!-- 中间Logo --> <item name="windowSplashScreenAnimatedIcon"> @drawable/ic_splash_logo </item> <!-- 启动后切换主题 --> <item name="postSplashScreenTheme"> @style/Theme.App </item> </style>

八、系统 Splash 能做到什么程度?

很多人以为:

系统 Splash 可以完全自定义

其实并不行。

系统 Splash 本质是:

Framework 半封闭模板

只能改:

能力是否支持
背景色
中间Logo
图标背景色
退出动画
倒计时
跳过按钮
XML布局
复杂背景
多控件排版

所以:

系统 Splash: 只能做“启动壳子”

真正复杂的企业启动页:

还是得:

自己写 Activity

九、企业项目应该怎么设计启动页?

这是现代 Android 企业项目最推荐方案。

正确方案

系统 Splash ↓ 企业 SplashActivity ↓ MainActivity

系统 Splash

负责:

  • 防白屏
  • 冷启动过渡
  • Android12 兼容
  • 系统统一体验

通常只做:

纯色背景 + 品牌Logo

企业 Splash

负责:

  • 倒计时
  • 广告
  • 企业品牌
  • 动画
  • 登录检查
  • 初始化逻辑

这才是现代 Android 项目的正确职责划分。


十、完整代码示例


10.1 Compose 项目推荐写法

Compose 时代:

推荐:

系统 Splash ↓ MainActivity ↓ Compose 企业 Splash ↓ HomeScreen

依赖

implementation "androidx.core:core-splashscreen:1.0.1"

themes.xml

<style name="Theme.App.Starting" parent="Theme.SplashScreen"> <item name="windowSplashScreenBackground"> @color/splash_bg </item> <item name="windowSplashScreenAnimatedIcon"> @drawable/ic_splash_logo </item> <item name="postSplashScreenTheme"> @style/Theme.App </item> </style>

MainActivity

class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() super.onCreate(savedInstanceState) setContent { var showSplash by remember { mutableStateOf(true) } if (showSplash) { EnterpriseSplashScreen( onFinish = { showSplash = false } ) } else { HomeScreen() } } } }

10.2 传统 XML 项目推荐写法

传统项目 推荐:

系统 Splash ↓ SplashActivity ↓ MainActivity

SplashActivity

class SplashActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() super.onCreate(savedInstanceState) setContentView(R.layout.activity_splash) object : CountDownTimer(2000, 1000) { override fun onTick(millisUntilFinished: Long) { } override fun onFinish() { startActivity( Intent( this@SplashActivity, MainActivity::class.java ) ) finish() } }.start() } }

十一、低版本设备有没有系统 Splash?

这是很多人容易误解的地方。

Android11 及以下

实际上:

没有真正系统 SplashScreen

只有:

windowBackground Preview

Android12+

才真正有:

Framework SplashScreen

十二、core-splashscreen 到底是什么?

很多人以为:

implementation("androidx.core:core-splashscreen:1.0.1")

会让所有系统都拥有:

系统 Splash

其实并不是。它只是:

AndroidX 兼容层

作用是:

统一 API

Android12+

调用:

真正系统 Splash

Android11-

只是:

兼容模拟

并不会:

凭空出现系统 Splash 页面

十三、能彻底绕过系统 Splash 吗?

结论:

Android12+ App层基本绕不过

因为:

系统 Splash 已经属于 Framework 启动链路

如果真想彻底去掉:

只能改 AOSP / Framework

已经属于:

ROM定制 Framework开发

范畴。


十四、面试怎么回答“白屏怎么处理”?

真正高级的回答:

Android 冷启动时, 在 Activity 真正绘制前, 系统会先显示 Starting Window。 Android11 及以下, 主要是 windowBackground Preview; Android12+, Google 引入统一 SplashScreen 机制。 因此现代 Android 推荐: Theme.SplashScreen + installSplashScreen() + 业务 Splash 解耦。 系统 Splash 负责防白屏, 业务 Splash 负责广告、倒计时、品牌展示。

这才是:

工程理解型回答

而不是:

“改个 windowBackground”

这么简单。


十五、总结

以前:

Splash 是业务页面

现在:

Splash 已经变成系统能力

这其实是:

Android Framework 启动机制的一次演进

以前:

我们是在 Activity 里做启动页

现在:

Android 已经把启动页变成了系统级能力
http://www.cnnetsun.cn/news/2519775.html

相关文章:

  • 全域数学·第三部·数术几何部·平行网格卷 完整专著目录(含拓扑发展史+学科定位·终稿)
  • N维平行整数网格论——基于离散组合拓扑与整数位置分析的全新数论体系
  • 不止于Windows:用QtService源码打造跨平台(Windows/Linux)守护进程的实践指南
  • 蓝桥杯嵌入式实战:手把手教你用STM32CubeMX和HAL库封装PWM控制函数(调频调占空比)
  • 保姆级教程:在YOLOv5s.yaml里给YOLOv5 V7.0模型加上SimAM注意力(附代码)
  • 国产多模态大模型 vs DALL-E:本土化突围与全球竞技
  • 从仿真翻车到波形完美:手把手教你用Multisim搞定LM741反相放大电路(含电源/电容配置避坑)
  • STM32F407 PWM呼吸灯实战:从CubeMX配置到代码调试,手把手教你玩转TIM14
  • 手把手教你用8255和12864 LCD搞定微机原理课设:一个公交报站器的完整实现
  • EI、SCI、Scopus傻傻分不清?一文讲透工程领域核心期刊数据库怎么选
  • MATLAB CVX工具箱保姆级安装与第一个凸优化问题实战
  • 从炼丹到炼蛋白:手把手拆解AlphaFold2的模型架构与训练技巧
  • 远程为海外公司工作的真实体验:钱多事少但有时差——一个软件测试工程师的深度拆解
  • NotebookLM支持实时字幕吗?不,它真正强悍的是这4种高阶语音语义重构能力
  • DeepSeek微服务拆分实战:从单体到弹性集群的7步标准化迁移手册(含流量染色+灰度发布Checklist)
  • 植入式网络广告效果影响因素及投放决策优化【附代码】
  • M1 Mac上搞定Tinker热修复:从7zip报错到成功生成补丁的完整踩坑实录
  • 观察不同时段调用 Taotoken 各类模型的延迟表现
  • Keil MDK中第三方软件包兼容性问题解析与解决
  • ngx_http_set_virtual_server
  • 当自动化运维系统被ai重构后
  • 全开源CRM客户关系管理系统源码完整部署指南附代码
  • RK3588下位机程序无响应问题排查
  • 微信小程序 智能停车场预约推荐系统
  • 嵌入式Linux开发:GDB远程调试ARM平台的完整实战指南
  • AI开发基础(第9篇):Harness Engineering与知识地图
  • 写给新手的 release-management:昇腾版本管理到底是啥?
  • AI Agent Harness Engineering 的安全性挑战:提示词注入与防御
  • RK3568核心板开发全攻略:从硬件选型到量产落地的嵌入式实战指南
  • 内存核心频率停滞20年:从等效频率到延迟优化的性能真相