转载请注明出处:http://blog.csdn.net/fishle123/article/details/50812266
在Activity中,常常第一件事就是在onCreate里面调用setContentView来设置布局。大家都知道setContentView用来设置Activity的布局,但是有没有研究过setContentView究竟做了哪些事呢?本文就一起看看setContentView是如何加载我们的布局的。看完之后大家就会知道为什么使用requestWindowFeature设置窗口风格的时候一定要在setContentView之前调用。
1 Window相关的基础知识
在Android里面,Activity的内容就是一个Window,Dialog和Toast也都是通过Window来展示的。在实际使用当中并不能直接访问Window,需要通过WindowManager才能访问到Window,WindowManager提供了addView、updateViewLayout和removeView三个方法来管理Window中的View。Window类是一个抽象类,它唯一的实现是PhoneWindow。在PhoneWindow里面有个属性mDecor,它的类型是DecorView,DecorView是PhoneWindow的内部类。DecorView是FrameLayout的子类,包含整个PhoneWindow所有要显示的View,包括系统的状态栏、标题栏、以及Activity的布局等,下面通过一张图来说明它们之间的关系,这张图展示了Activity的默认视图结构。
从这张图可以很清楚看到,Android中看到的视图都是通过Window来呈现,具体地是通过PhoneWindow来管理的。需要说明的是不同样式风格的Window内部视图结构可能会有所不同,比如有的Window没有TitleBar,但是mContentParent是一定要有的。DecorView对应着Widnow要呈现的内容。我们通过setContentView设置的其实是mParentConent的子View,mParentContent对应的id是com.android.internal.R.id.content,因此使用setContentView就非常贴切了。
2 setContentView源码分析
在onCreate里面调用的是Activity的setContentView,setContentView有三个重载版本,它们的逻辑都是差不多的,这里就看一下setContentView(int layoutResID)的源码:
1)Activity的setContentView最终是调用Window的setContentView
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
这里可以看到,Activity其实是调用Window的setContentView来加载布局的。
2)初始化DecorView--根据Window的样式风格选定布局并加载,然后把Activity的布局添加到DecorView中
上面有提到Window类是一个抽象类,唯一实现了Window的是PhoneWindow。下面就是看一下PhoneWindow的setContentView: