StartingWindow
// frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
boolean createStartingWindow(...) {
...
mWmService.mStartingSurfaceController.addStartingWindow(this);
}
这段代码是系统在启动 Activity 过程中插入启动窗口(包括 SplashScreen)的关键路径。我们来详细剖析这段代码的实现背景、调用链和最终效果:
1. 背景
当 Android 应用启动时(冷启动或首次启动某个 Activity),为了避免用户看到黑屏,系统会在应用真正绘制前插入一个“占位窗口”,通常是:
• SplashScreen(Android 12+)
• 或老版本的 StartingWindow(如 preview window)
🔍 2. 核心调用链梳理
你提到的是:
// ActivityRecord.java
boolean createStartingWindow(...) {
...
mWmService.mStartingSurfaceController.addStartingWindow(this);
}
这段代码的调用链如下:
ActivityTaskManagerService.startActivity()
↳ ActivityStackSupervisor.realStartActivityLocked()
↳ ActivityRecord.attach() -> 创建 WindowToken
↳ ActivityRecord.createStartingWindow()
↳ StartingSurfaceController.addStartingWindow()
也就是说:当系统即将启动某个 Activity 时,会判断是否要添加一个“起始窗口”。
3. addStartingWindow() 做了什么?
这个函数负责:
创建 SplashScreenView 或 legacy StartingWindow
// frameworks/base/services/core/java/com/android/server/wm/StartingSurfaceController.java
boolean addStartingWindow(ActivityRecord activity) {
// 判断是否启用 SplashScreen(API 31+)
if (mSplashScreenController != null && activity.shouldUseSplashScreen()) {
return mSplashScreenController.addSplashScreenStartingWindow(activity, ...);
} else {
// fallback: 使用老版 StartingWindow(TextView + 背景色)
return createLegacyStartingWindow(activity);
}
}
系统在这里判断当前 Activity 是否应该使用 SplashScreenView,如果不行则回退到老方案(白底+app icon+label)
4. SplashScreenController.addSplashScreenStartingWindow(…)
该方法最终构造了:
// 创建 SplashScreenView
SplashScreenView view = new SplashScreenView(...);
// 将 View 添加到应用窗口
WindowState.addChild(view);
SplashScreenView 是一个系统级的 View,由 android:windowSplashScreenAnimatedIcon 和 windowSplashScreenBackground 控制内容。
** 5. 为什么叫 “StartingWindow”?和 Splash 有何关系?**
• 在 Android 12+ 中,“起始窗口”就是 SplashScreen;
• 在旧版本中,“起始窗口”是通过 TextView + 背景色手动构建的 preview 窗口;
• 系统使用 相同的接口 addStartingWindow() 注入起始界面,内部根据条件决定是否创建 SplashScreen。
6. 关键点总结
关键点 | 说明 |
---|---|
createStartingWindow() | ActivityRecord 启动前构建占位窗口 |
mWmService.mStartingSurfaceController | 控制 Splash 的插入逻辑 |
addStartingWindow() | 自动判断是否构建 SplashScreen |
SplashScreenController | Android 12+ 新引入的系统类,用于统一展示启动画面 |
SplashScreenView | 系统实际展示在屏幕上的 View(背景 + 图标 + 动画) |
相关源码文件(AOSP)
类名 | 作用 | 文件路径 |
---|---|---|
ActivityRecord.java | 管理单个 Activity 启动状态 | services/core/java/com/android/server/wm/ |
StartingSurfaceController.java | 控制启动窗口的创建 | 同上 |
SplashScreenController.java | Android 12+ 专用于管理 SplashScreen | 同上 |
SplashScreenView.java | 实际展示的 View | core/java/com/android/internal/policy/ |