这个是26版本的源码啊
1、Activity setContentView
![](https://i-blog.csdnimg.cn/blog_migrate/d5c95ce70d7c2402e75f89258983b6f0.png)
image.png
getWindow().setContentView(layoutResID);
getWindow 返回的是window
![](https://i-blog.csdnimg.cn/blog_migrate/ccfd09b96c655fc4c38356fcf0574188.png)
image.png
而Window是一个抽象类
![](https://i-blog.csdnimg.cn/blog_migrate/8dd06ab259a9fb4ce7c612228e0d9959.png)
image.png
它有一个唯一的实现类 是phoneWindow
phoneWindow的setContentView
![](https://i-blog.csdnimg.cn/blog_migrate/0636505f5d00d75783865cf619a6f7be.png)
image.png
installDecor方法
![](https://i-blog.csdnimg.cn/blog_migrate/8ad84c365c0d9f7906c586ce3acf9609.png)
image.png
generateDecor 返回了一个DectorView
![](https://i-blog.csdnimg.cn/blog_migrate/05bebfcaf94b20e188ea11b40c8def7c.png)
image.png
我们要知道 这个 DectorView是一个FrameLayout
![](https://i-blog.csdnimg.cn/blog_migrate/704de3c212139e5c43d33f03421f12aa.png)
image.png
genratelayout 方法
![](https://i-blog.csdnimg.cn/blog_migrate/e7597f9e430ffffc1ef442559096afab.png)
image.png
在其方法内部有这个方法 (onResoureLoaded )
![](https://i-blog.csdnimg.cn/blog_migrate/7aa27c1abfdf394361501fe32ebc1e8d.png)
image.png
通过上面 generateDecor 生成的DectorView 传过来 调用
mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
我们看一下 onResourcesLoaded 方法 同时注意一个 layoutResource 这个参数
layoutResource 这个参数的取值是 一个布局文件 layout 是系统定义的 (通这上面不用的feature(them)来确定的)比如有没有actionBar
我们发现在它有一个addView的动作
![](https://i-blog.csdnimg.cn/blog_migrate/d32c0ba08b23009e4281c363cc27c728.png)
image.png
这里我们要确定这个root是谁 (这个root就是系统布局通过inflate 生成的View)
![](https://i-blog.csdnimg.cn/blog_migrate/54f29f75fe1cf773624fd17f0497a6cb.png)
image.png
addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
这个addView 是 DectorView调用的
也就是说方法走到这里 DectorView 调用了一次addView 而添加的View还是系统的布局 还不是我们setContentView的 layoutId呢
我们在看这里 findViewById(ID_ANDROID_CONTENT) (距离真相越来越近了)
protected ViewGroup generateLayout(DecorView decor) {
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
return contentParent;
}
//在这里找到 id 是 ID_ANDROID_CONTENT 的 layout 当然这个 id 是 存在于 layoutResource 中的
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
我们发现在 generateLayout 是把 ID_ANDROID_CONTENT 是ViewGroup返回了
ok我们返回到 PhoneWindow的setContentView
看一下mContentParent是在哪里赋值的?
![](https://i-blog.csdnimg.cn/blog_migrate/616c2d1096623b7650ef0103641498af.png)
image.png
也就是说 这个mContentParent是通过 genrateLayout这个方法生成的
这句话很重要
mContentParent 是DectorView(添加了系统定义的layout布局)中 id 是 ID_ANDROID_CONTENT 的ViewGroup
![](https://i-blog.csdnimg.cn/blog_migrate/8544b4fb75ed6ad3608f4faed99b70a4.png)
image.png
然后通过inflate 把布局添加到 id 是 ID_ANDROID_CONTENT 的ViewGroup中
![](https://i-blog.csdnimg.cn/blog_migrate/306c67f54cee77f3e4f26a97995515ef.png)
image.png
![](https://i-blog.csdnimg.cn/blog_migrate/9544d785c5856712530894c02eab4d8c.png)
image.png