SplashScreen详细

好的,我们系统地讲解 SplashScreen(启动屏幕)在 Android 中的 用法、背景、场景、注意事项和实现原理,以现代(API 31+)和旧版方式结合的方式展开。

一、用法(现代 API:Android 12+, 推荐)

从 Android 12 开始,Android 提供了标准化的 SplashScreen 机制,避免各厂商和开发者使用不一致的“首帧卡顿 + 跳转 Activity”方案。

基本用法:

1. 依赖库(向下兼容)

dependencies {
    implementation "androidx.core:core-splashscreen:1.0.1"
}

2. 配置主题

<!-- values/themes.xml -->
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight">
    <!-- 设置启动背景 -->
    <item name="android:windowSplashScreenBackground">@color/white</item>
    <!-- 设置启动图标 -->
    <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_launcher_foreground</item>
    <!-- 图标动画的持续时间 -->
    <item name="android:windowSplashScreenAnimationDuration">500</item>
    <!-- 是否自动移除动画图标 -->
    <item name="android:postSplashScreenTheme">@style/Theme.MyApp</item>
</style>

3. 在 Activity 中启用 SplashScreen

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        val splashScreen = installSplashScreen()

        // 控制 splash 屏幕保留时间(比如等数据加载完)
        splashScreen.setKeepOnScreenCondition {
            viewModel.isLoading.value
        }

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

二、产生背景(为什么需要 SplashScreen?)

启动初期的问题:

• 首帧绘制前,可能出现白屏/黑屏;

• 如果初始化时间较长,用户感知为“卡住了”;

• 各厂商 ROM 自己实现 Splash 导致 UI 不一致。

目标:

提供一致性体验

向用户表明 App 正在启动

优雅过渡,消除视觉突兀

三、实际应用场景

场景 是否推荐使用 SplashScreen
App 冷启动时展示品牌 Logo ✅ 推荐
启动过程中加载网络资源或本地数据 ✅ 推荐
App 快速启动但想做品牌展示 ✅ 可以用动画缩短时间
热启动/Activity 切换 ❌ 不建议使用

** 四、注意事项**

项目 说明
不要用 SplashActivity 跳转 Android 12+ 系统已统一处理;旧方案容易出现跳转闪烁/ANR
不要延迟启动主 UI installSplashScreen() 后立即加载主界面,Splash 会自己处理显示
尽量不加 Handler 延时跳转 延时器不确定,用户设备性能差异大,体验差
自定义图标动画尽量不阻塞主线程 会卡顿,建议在 background 线程加载数据

🔍 五、实现原理(系统角度)

1. 系统流程(简略)

1. App 冷启动时,系统先显示 windowSplashScreenBackground 背景 + windowSplashScreenAnimatedIcon;

2. 在 ActivityThread.handleLaunchActivity() 时设置窗口;

3. 直到 ViewRootImpl.performDraw() 中调用 finishDrawing()

• 通知 WindowManager:主窗口绘制完了;

4. 系统这才移除 SplashScreen,正式展示主 UI。

2. 核心变量

• mReportNextDraw = true:即使 Activity 还未 resume,也强制绘制一帧(否则 Splash 不移除);

• WindowManagerService:监控主窗口是否绘制完成;

• Choreographer + Vsync:协调绘制时机;

• SplashScreenView:系统用于 Splash 的 View,统一控制动画、过渡等。

总结

项目 推荐实践
实现方式 使用 installSplashScreen()
背景图设置 用 windowSplashScreenBackground
控制展示时长 用 setKeepOnScreenCondition {} 绑定加载状态
主题切换 用 postSplashScreenTheme 切换到主主题
不推荐 使用 SplashActivity + 延时跳转等旧方式

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器