当前位置: 首页 > 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 时实际上会先创建一个Starting Window然后显示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没有配置。系统默认通常就是白色。于是用户看到 白一下五、Android12API31到底改变了什么真正的变化 发生在Android12API31Google 正式引入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 nameTheme.App.Starting parentTheme.SplashScreen !-- 背景 -- item namewindowSplashScreenBackground color/splash_bg /item !-- 中间Logo -- item namewindowSplashScreenAnimatedIcon drawable/ic_splash_logo /item !-- 启动后切换主题 -- item namepostSplashScreenTheme 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.1themes.xmlstyle nameTheme.App.Starting parentTheme.SplashScreen item namewindowSplashScreenBackground color/splash_bg /item item namewindowSplashScreenAnimatedIcon drawable/ic_splash_logo /item item namepostSplashScreenTheme style/Theme.App /item /styleMainActivityclass 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 ↓ MainActivitySplashActivityclass 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( thisSplashActivity, MainActivity::class.java ) ) finish() } }.start() } }十一、低版本设备有没有系统 Splash这是很多人容易误解的地方。Android11 及以下实际上没有真正系统 SplashScreen只有windowBackground PreviewAndroid12才真正有Framework SplashScreen十二、core-splashscreen 到底是什么很多人以为implementation(androidx.core:core-splashscreen:1.0.1)会让所有系统都拥有系统 Splash其实并不是。它只是AndroidX 兼容层作用是统一 APIAndroid12调用真正系统 SplashAndroid11-只是兼容模拟并不会凭空出现系统 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.zskr.cn/news/1351982.html

相关文章:

  • 基于Python + LLM的AI导演:让多智能体协作自动完成复杂任务
  • 别再只盯着CNN了!用MedViT这个混合模型,搞定医学图像分类的鲁棒性难题
  • 洛克王国:世界 — 解包与 Mod 尝试完整记录
  • 避开BLE开发第一个坑:搞懂广播帧里的TxAdd、ChSel字段,让你的智能硬件不再‘隐身’
  • C++ Kafka实战:用librdkafka手写一个带自定义分区和事件回调的生产者
  • 我踩了N多劣质工具坑从嫌弃到真香,2026这款语音生成软件真后悔没早用
  • 2026 年一人公司创业热潮:政策与 AI 驱动,机遇背后暗藏风险
  • Vue 3 + 高德地图实战:打造全能定位与搜索组件
  • 2026年多门店商城小程序怎么做
  • 告别一堆转接头!一个自研小工具搞定USB、网口、485、232、TTL互转(附配置教程)
  • 保姆级教程:在YOLOv5s.yaml里给YOLOv5 V7.0模型加上SimAM注意力(附代码)
  • 减速机:以“减速”之名,行“增力”之实的机械智慧
  • 【c++面向对象编程】第46篇:CRTP(奇异递归模板模式):静态多态的妙用
  • 国产多模态大模型 vs DALL-E:本土化突围与全球竞技
  • 别再只调样式了!深入理解鸿蒙ArkTS中Slider的四种交互状态(Begin/Moving/End/Click)
  • 手把手教你用C语言写一个简易的SMTP邮件内容解析器(基于libnids抓包库)
  • 【c++面向对象编程】第44篇:typename与class的区别,依赖类型名与template消除歧义
  • 告别开发依赖!SAP顾问必学的SQ01/SQ02/SQ03实战:5步搞定自定义报表
  • DocKit v1.0 发布 — AI 原生 NoSQL 桌面客户端,支持 Elasticsearch、OpenSearch 和 DynamoDB,本地优先,Apache 2.0 开源
  • 21.jdbc 学习笔记:从原理到实践的全流程梳理
  • 20.MySQL事务隔离级别示例详解(脏读、不可重复读、幻读)
  • 化妆品俄罗斯 Honest Sign诚实标签采集技术方案解析
  • Klogg实战:5分钟搞定海量日志中的Error排查(颜色标记+正则过滤技巧)
  • 炉石传说佣兵战记自动化脚本完整指南:5步轻松实现自动战斗
  • RK3588/3568嵌入式视觉开发:为什么我选择OpenCV 3.4.3 + FFmpeg 4.2.9这个“经典组合”?
  • 避开RK3566以太网PHY调试的那些‘坑’:从硬件C15到DTS配置的完整避坑指南
  • 众汇量化以多策略融合与智能投研打造高质量投资体系
  • 告别 GPU 独占时代:用 HAMi 实现训练推理一体化——博维智慧 GPU 虚拟化实战
  • 复合AI系统基准测试与优化实践指南
  • BE-ToF技术:突破传统飞行时间成像的深度感知新方案