DecorView的创建
**DecorView **是在 PhoneWindow.installDecor() 方法中创建的。
DecorView 的创建时机:
是在你调用 setContentView() 之前的 installDecor() 中完成的。
🔍 源码追踪过程
1️⃣ Activity 中的调用:
// Activity.java
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
}
2️⃣ PhoneWindow 中的处理:
// PhoneWindow.java
@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor(); // ⚠️ 此处创建 DecorView
}
...
}
3️⃣ 创建 DecorView:
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor(-1); // ⚠️ 创建 DecorView
}
...
}
protected DecorView generateDecor(int featureId) {
return new DecorView(context, featureId, this); // 直接构造
}
所以:
• DecorView 是在 installDecor() → generateDecor() 中创建的;
• installDecor() 是在 setContentView() 中调用的;
• 但不是 setContentView() 中构建的布局 View,而是整个 Window 的根容器。
🏗️ 举个简单结构图:
Activity.setContentView(R.layout.xxx)
↓
PhoneWindow.setContentView
↓
┌─────────────┐
│ DecorView │ ← 这是系统自动创建的根 View
└─────────────┘
↓
┌─────────────────┐
│ R.layout.xxx │ ← 你传入的布局内容
└─────────────────┘
总结
项 | 说明 |
---|---|
DecorView 创建时机 | installDecor() 中(早于 setContentView()) |
setContentView() 做了什么 | 向 DecorView 中的 contentParent 添加你自己的布局 |
DecorView 的背景 | 来自当前 Theme 的 windowBackground 属性 |
白屏出现的原因 | DecorView 已添加窗口并显示了默认背景,用户内容尚未添加 |