每次都有,但可控
默认情况下,每次启动一个新的 Activity,系统都会尝试为它创建一个 StartWindow,不只是 MainActivity 有。
但也存在一些前提条件和例外,我们逐一说明。
一、系统是否创建 StartWindow 的判断逻辑
关键代码在:
// ActivityRecord.java
boolean createStartingWindow(...) {
// 多个前置条件判断
if (!okToShowStartingWindow()) return false;
mWmService.mStartingSurfaceController.addStartingWindow(this);
}
系统不是“无脑创建”,而是基于如下条件:
条件 1:必须是“可见的 Activity”
// ActivityRecord.java
boolean okToShowStartingWindow(...) {
return isVisible() && !mTask.isSleeping() && ...;
}
条件 2:该 Activity 的 intent 不是 NO_ANIMATION
如果设置了:
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
或者使用 overridePendingTransition(0, 0) 把过渡动画禁用了,也不会创建。
条件 3:应用配置允许展示
默认允许,但可通过 android:windowDisablePreview 禁用(后文详解)。
二、那为什么 MainActivity 最常见有 StartWindow?
• MainActivity 通常是冷启动场景(进程未启动);
• 冷启动时,系统有显著延迟,所以非常需要 StartWindow;
• 后续跳转的新 Activity,大多数是热启动,App UI 构建更快;
• 如果有 overridePendingTransition() 动画,系统可能判断无需 StartWindow。
所以用户体验上感知为 “好像只有 MainActivity 有”。
三、可以通过 Manifest 控制是否启用 StartWindow
<activity
android:name=".MyActivity"
android:theme="@style/MyTheme"
android:windowDisablePreview="true" /> <!-- 禁用 StartWindow -->
四、实际案例说明
场景 | 是否创建 StartWindow | 说明 |
---|---|---|
第一次启动 MainActivity(冷启动) | ✅ 创建 | 提高冷启动体验 |
从 A → 启动 B(显式跳转) | ✅ 创建 | 若未禁用,正常创建 |
启动 B,同时设置 NO_ANIMATION | ❌ 不创建 | 动画禁用了,系统会跳过 |
启动 B,同时配置 android:windowDisablePreview=”true” | ❌ 不创建 | 开发者显式禁用 |
B 是透明或 Dialog 类型 Activity | ❌ 不创建 | 背景透明,StartWindow 无意义 |
五、总结
问题 | 回答 |
---|---|
是否每个 Activity 启动都有 StartWindow? | ✅ 默认是的,系统都会尝试创建 |
只有 MainActivity 有 StartWindow 吗? | ❌ 不是,任何 Activity 启动理论上都可能有 |
是否可以关闭? | ✅ 可以通过 android:windowDisablePreview=”true” 或 NO_ANIMATION 禁用 |
创建依据? | 是否可见、是否是冷启动、是否允许动画、是否被禁用等 |