Manifest中设置的android_theme什么时候生效
在 AndroidManifest.xml 中:<activity
android:name=".MainActivity"
android:theme="@style/Theme.App.Launch"> <!-- 启动时使用的临时主题 -->
</activity>
这个 Theme.App.Launch 是什么时候起作用的?
Manifest 中设置的 android:theme 是在什么时候生效、由哪段代码加载的?
结论先行:
Manifest 中配置的:
<activity android:theme="@style/Theme.App.Launch" />
会在系统启动该 Activity 实例并构建它的 Context 时,被系统自动加载并应用到该 Activity 的 Window 上,在你调用 onCreate() 之前就已经生效了。
📌 谁加载了这个 theme?
是在 Activity.attach() 方法中,通过 ContextThemeWrapper 设置的:
🔍 源码路径:
// /frameworks/base/core/java/android/app/Activity.java
@UnsupportedAppUsage
final void attach(...) {
...
// 这行非常关键:创建主题并绑定到 Context
mActivityInfo = aInfo;
mTheme = getResources().newTheme();
mTheme.setTo(r.getTheme());
// 从 ActivityInfo 中读取主题(也就是 Manifest 中配置的 Theme)
final int theme = aInfo.getThemeResource();
if (theme != 0) {
mTheme.applyStyle(theme, true); // <-- 应用 Theme.App.Launch
}
...
// 设置 Context 中的 themeId
mThemeResource = theme;
// 将 theme 传递给 LayoutInflater 等内部组件
initializeTheme();
}
📌 这个 aInfo.getThemeResource() 来自哪里?
系统在解析 AndroidManifest.xml 时,会把 <activity> 标签中的 android:theme 解析成一个整数资源 ID(如 R.style.Theme_App_Launch),保存在 ActivityInfo.theme 字段中。
🧠 小结:
阶段 | 行为 | 说明 |
---|---|---|
应用进程创建前 | 系统解析 Manifest,获取 ActivityInfo,包括 theme | ActivityInfo.theme 保存了 @style/Theme.App.Launch 的资源 ID |
启动 Activity | ActivityThread.performLaunchActivity() 中调用 Activity.attach() | 将 Manifest 中配置的 theme 设置到 Activity 的 Context 和 Window |
调用 onCreate() 之前 | Theme 已生效,显示的背景已经是 Theme.App.Launch 设置的背景(如 logo、纯色) | 所以你看到的是启动页界面,不是白屏 |
👇 补充:调用链大致如下
ActivityThread.handleLaunchActivity()
↳ performLaunchActivity()
↳ Instrumentation.newActivity()
↳ Activity.attach()
↳ mTheme.applyStyle(themeId, true) // <== 应用 Manifest 中的 theme