补充说明Window、PhoneWindow与DecorView

补充说明Window、PhoneWindow与DecorView

在前面 Android用户界面与View/ViewGroup 这一小节中,我们大概理解了View/ViewGroup的概念。但是它们仅仅是界面的一部分,正如下图所示:

对相关类的作用进行一下简单介绍:

Window 类 位于 /frameworks/base/core/java/android/view/Window.java。该类是一个抽象类,提供了绘制窗口的一组通用API。可以将之理解为一个载体,各种View在这个载体上显示。

PhoneWindow类 位于/frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindow.java。该类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。 简而言之,PhoneWindow类是把一个FrameLayout类即DecorView对象进行一定的包装,将它作为应用窗口的根View,并提供一组通用的窗口操作接口。

DecorView类 该类是PhoneWindow类的内部类。该类是一个FrameLayout的子类,并且是PhoneWindow的子类,该类就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等 。最重要的一点是,它是所有应用窗口的根View 。

打个不恰当比喻吧,Window类相当于一幅画(抽象概念,什么画我们未知) ,PhoneWindow为一副齐白石先生的山水画(具体概念,我们知道了是谁的、什么性质的画),DecorView则为该山水画的具体内容(有山、有水、有树,各种界面)。DecorView呈现在PhoneWindow上。

当系统(一般是ActivityManagerService)配置好启动一个Activity的相关参数(包括Activity对象和Window对象信息)后,就会回调Activity的onCreate()方法,在其中我们通过设置setContentView()方法类设置该Activity的显示界面,整个调用链由此铺垫开来。setContentView()的三个构造方法调用流程本质上是一样的,我们就分析setContentView(intresId)方法。

Activity.setContentView(intresId) 该方法在Activity类中,该方法只是简单的回调Window对象,具体为PhoneWindow对象的setContentView()方法实现。

1

public void setContentView(int layoutResID) {

2

getWindow().setContentView(layoutResID);

3

}

4

5

public Window getWindow() {

6

return mWindow; //Window对象,本质上是一个PhoneWindow对象

7

}

PhoneWindow.setContentView() 该方法在PhoneWindow类中

01

@Override

02

public void setContentView(int layoutResID) {

03

//是否是第一次调用setContentView方法, 如果是第一次调用,则mDecor和mContentParent对象都为空

04

if (mContentParent == null) {

05

installDecor();

06

} else {

07

mContentParent.removeAllViews();

08

}

09

mLayoutInflater.inflate(layoutResID, mContentParent);

10

final Callback cb = getCallback();

11

if (cb != null) {

12

cb.onContentChanged();

13

}

14

}

该方法根据首先判断是否已经由setContentView()了获取mContentParent即View对象, 即是否是第一次调用该PhoneWindow对象setContentView()方法。如果是第一次调用,则调用installDecor()方法,否则,移除该mContentParent内所有的所有子View。最后将我们的资源文件通过LayoutInflater对象转换为View树,并且添加至mContentParent视图中。

因此,在应用程序里,我们可以多次调用setContentView()来显示我们的界面。

🎯 相关推荐

大拇指指甲上有竖纹是怎么回事
365bet真人体育

大拇指指甲上有竖纹是怎么回事

📅 08-31 👁️ 6402
镇魂武器怎么选?50天速成攻略+开光避坑指南
365bet真人体育

镇魂武器怎么选?50天速成攻略+开光避坑指南

📅 07-24 👁️ 3412
图像处理之图像灰度化
日博best365

图像处理之图像灰度化

📅 07-04 👁️ 5269
科普丨蘑菇到底是不是植物?
日博best365

科普丨蘑菇到底是不是植物?

📅 08-22 👁️ 5190
为什么文件以只读方式打开?
best365官网苹果下载

为什么文件以只读方式打开?

📅 08-03 👁️ 4524
武林外传寻宝网交易具体流程?(武林外传寻宝体现多长时间能到账)