setContentView是如何一步一步被显示出来的?
通常我们在onCreate中会调用setContentView方法,如下:

setContentView里面优势怎么样执行的呢,进去看看,如下:

跳转到getWindow().setContentView(layoutResID)如下:

Window类型的继承树如下:

Window只有一个实现类PhoneWindow,那也就是说getWindow().setContentView(layoutResID)调用的是PhoneWindow的setContentView,如下:

先来看看上图中标记A的地方,调用installDecor方法,看名字的意思是创建decor的意思,而这个decor如果你熟悉Adroid 视图的层级结构的话,会一下子就理解,这里我给一张图帮助你理解:

DecorView实际上是作为Activity上的视图的最顶层View,而我们自己的布局则是上图粉色区域,外面还包含着一层,称之为contentParent,从名字上看也是取得很贴切,嗯还是进入源码看看一下是不是上图描述的那样,如下:

genereteDecor方法调用如下:

generateLayout方法如下:

至此可以看到最顶层布局,以及我们自己的布局的复布局都已创建好了,回到上图标记B 的地方,可以看到调用了 mLayoutInflater.inflate(layoutResID, mContentParent);
这个layoutResID就是我们自己的布局的id,调用完这一句我们自己的布局也被创建出来了,到这里你应该会有一个疑问:Activity的整个View视图都被创建好了,那么接下来应该是要绘制这个视图才对,我第一次看这个源码的时候也是有这个疑问,同时还犯了一个错误,我试图在mLayoutInflater.inflate(layoutResID, mContentParent);这句之后查找开启绘制试图的代码,查看源码我根本就找不到,一下子就懵逼了,如下:

其实这是我忽略了一个事实,这个setCotentView 是在onCreate被调用的这个时候View是不能见,真正能见的是在onResum时候,对哦,恍然大悟!!如果你有阅读之前的那篇Activity生命周期回调是如何被回调的?应该会知道onResume何时开始被调用,如下:


上图这个方法是在ActivityThread类中的,看到标记E的地方,是开始Activity的onResume的调用,进去看看,如下:

进入wm.addView看看如何,调用的是它的实现类WindowManagerImpl的addView如下:

跳转如下:

ViewRootImpl调用setView如下:

setView方法里面调用了requestLayout,这个方法名让我们看到了是在做绘制View视图的苗头,进去看看是不是如此:


mTraversalRunnable对象的类相貌如下:

可以看到在run方法里面调用doTraversal,如下:

performTraversals方法的代码是在是太长了,这里我不截图,这个方法里面调用了三个关键的方法:performMeasure方法开启视图的测量流程,performLayout方法开启了视图的布局流程,performDraw开启了视图的绘制流程,这3个方面的具体细节我准备在其他篇章来介绍,这3个流程走完,视图就会被真正的绘制完成。到此setContentView的工作是如何一步一步被现实的,你是否有一个比较深的理解了,回顾一下前面讲的东西,可以总结如下:
1.setContentView只是将Activity的整个View视图创建好,放在一边而已,而执行创建View视图的则是PhoneWindow
2.在Activity在准备转换成Resume状态的之际,即调用handleResumeActivity,会将最顶层View——DecorView兜兜转转传到WindowManagerGlobal 手中
3.DecorView在WindowManagerGlobal 手中,首先先添加进View数组方便管理同时会为这个DecorView也可以说是这个视图创建一个ViewRootImpl
4.ViewRootImpl 将调用setView 将DecorView传入,开启绘制之旅
5.所以从前四步来看,真正导致Activity整个视图会被绘制的罪魁祸首是WindowManagerGlobal