什么是 Activity、View、Window?
Activity 是四大组件之一,也是我们的界面载体,可以展示页面;
而 View 实际上就是一个一个的视图,这些视图可以搭载在一个 Layout 文件上,通过 Activity 的 setContentView()
方法传递给 Activity;
Window 是一个窗体,每个 Activity 对应一个 Window,通常我们在代码中用 getWindow() 来获取它。
你是怎样理解它们三者之间的关系的?
Activity 像一个工匠 ( 控制单元 ),Window 像窗户 ( 承载模型 ),View 像窗花( 显示视图 ) LayoutInflater 像剪刀,Xml 配置像窗花图纸。
比喻挺生动,请问可以通俗一点么?
Activity 下装了一个 Window,Window 下装了 View,呃...
我们来直接看看实战中的代码,相信大家都知道 Activity 通过 setContentView()
方法来加载布局,我们来看看 setContentView()
方法到底是怎样做的。
(注释:将活动内容设置为显式视图。该视图直接放置在活动的视图层次结构中。它本身可以是一个复杂的视图层次结构。)
实际上是 getWindow().setContentView()
做的处理,那这个 getWindow()
?
你想的没错,这个 mWindow 实际上就是 PhoneWindow。Window 是一个抽象类,而 PhoneWindow 实际上就是 Window 的实现继承类。我们直接看看 PhoneWindow 的 setContentView()
方法,看看会有什么新发现?
先判断了 mContentParent
是否为空,这个 mContentParent
是什么玩意儿?
这个 mContentParent
是一个 ViewGroup 对象,而从注释中可以明显地看到 Window 中的内容就放置在这里。如果为空,则直接执行 installDecor()
,这里想都不用想都知道是在实例这个 mContentParent
,我们可以直接进入源码来验证我们的猜想。
这里代码挺多,我就不截完了,但逻辑不难,我们先判断 mDecor
是否为 null,如果是,则直接初始化它。然后判断 mContentParent
是否为 null,如果是,则直接通过 mDecor
去初始化 mContentParent
。
这块其实讲到这里大家就差不多了解了,这个问题也就不那么难答。
每个 Activity 包含了一个 Window 对象,这个对象是由 PhoneWindow 做的实现。而 PhoneWindow 将 DecorView 作为了一个应用窗口的根 View,这个 DecorView 又把屏幕划分为了两个区域:一个是 TitleView,一个是 ContentView,而我们平时在 Xml 文件中写的布局正好是展示在 ContentView 中的。
用个图展示一下。