第一问:什么是Activity、View、Window?
Activity 是四大组件之一,也是我们的界面载体,可以展示页面;而View实际上就是一个一个的视图,这些试图可以搭载在一个Layout文件上,通过Activity的setContentView()方法传递给Activity;Window是一个窗体,每个Activity对应一个Window,但是每个Window并不是对应的只是Activity,通常我们在代码中用getWindow()来获取它。
第二问:你是怎么样理解他们三者之间的关系的?
Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图),LayoutInflater像剪刀,获取有用的view,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中的,
用这个图展示一下。
说到这里,大致说完了,也不知道我说清楚了没有,持各种想法得朋友们可以下评论区留言,把你的想法让更多的人看到。