一、View是如何被添加到屏幕窗口上的?
1)找到入口:setContentView(int layoutResID)

点进去,进入 Activity的 setContentView()。

2)getWindow()是什么?

从这里可以看出,getWindow()就是单纯返回一个 Window对象。

根据注释,得知 Window是作为最高级别的视图添加到 WindowManager,并且 PhoneWindow是它的唯一实现类。也就是说,getWindow.setContentView()直接去看 PhoneWindow的setContentView()干了些什么就可以了。
3)PhoneWindow的 setContentView() 做了些什么?

接着看 installDecor()里面的代码,里面太长,有150行,只好删掉一些不太重要的代码。
4)PhoneWindow的 installDecor()干了些什么?

删掉了大部分的什么 background、UI、Logo、Title、Icon这类的设置,把核心的提取。
mDecor = generateDecor(-1)里面干了些什么?
结论:生成一个 DecorView对象,此对象本质是一个 FrameLayout!
下面看 5)论证。
mContentParent = generateLayout(mDecor)里面干了什么?
结论:得到一个 FrameLayout。
下面看 6)论证。
5)generateDecor(-1)里面干了些什么?

删掉大部分代码,可以看出,返回了一个 DecorView对象,那么这个 DecorView是什么东东?

官方没有注释,但是可以知道,实际上, DecorView就是一个 FrameLayout。
6)generateLayout(mDecor)里面干了什么?


1,通过各种判断,设置一大堆样式,主题特性等。setFlags()、requestFeauter()。
2,通过不同的 feature值,选定 layoutResource的值,并执行 mDecor.onResourcesLoaded()
3,获取系统主布局。final int ID_ANDROID_CONTENT = com.android.internal.R.id.content;
点进去就是这么个 ID。
结论:返回一个 contentParent,这本质是一个 FrameLayout。(证明看 7)
7)mDecor.onResourcesLoaded()干了些什么?

通过 layoutReouce创建一个 View对象,此对象可以就是上面根据不同 feature选取的值,例如:R.layout.screen_simple(系统 XML),在通过 addView()把 View对象加载到 DecorView上。

通过查看,这个根据不同条件选择的必定含有的 ID:content,本质是一个 FrameLayout。
继续回到 Activity的 setContentView()

8)mLayoutInflater.inflate(layoutResID, mContentParent)
最后,将在activity上设置的布局 layoutResID 加载到 contentParent上 也就是 FrameLayout上。至此,我们的整个View就加载并显示到屏幕上了。
总结:
1).创建顶层的布局容器DecorView。
2)在顶层布局中加载基础布局的ViewGroup
3)将ContentView添加到基础布局中的FrameLayout中。
view是如何被添加到屏幕窗口上的?
首先系统会创建一个顶层布局容器DecorView。DecorView 是一个ViewGroup容器, 继承FrameLayout,是PhoneWindow对象持有的一个实例,他是所有应用程序的顶层View,在系统内部进行初始化。当DecorView 初始化完成后,系统会根据应用程序的顶层特性会加载一个基础容器,例如no_actionBar等,不同的主题加载的基础容器也不一样,但是无论什么样的的基础容器一定会有一个 android.R.di.content 的FrameLayout。开发者通过setContView设置的xml ,通过解析后就加载到了这个FrameLayout中

网友评论