PS:本文为转载文章,原文可读性会更好,文末有原文链接ps:出处代码基于androidapi27进行分析,本文我们分析Activity的setContentView方法到底做了什么?有些读者可能会有疑问。文章有些地方看不懂怎么办。不明白的地方可以先跳过,看完这篇文章以后再google不明白的地方;(2)不懂的地方先google一下,再继续看这篇文章。好了,言归正传,我们来看Activity的setContentView方法;publicvoidsetContentView(@LayoutResintlayoutResID){getWindow().setContentView(layoutResID);initWindowDecorActionBar();}这里的getWindow方法获取的是Window对象,这个Window是Display顶级窗口的外观,封装了findViewById和事件分发等一些基本行为,每个Window都会添加到WindowManager中。Window的唯一实现类是PhoneWindow,所以getWindow方法得到的是Window对象,本质上就是PhoneWindow对象;如何知道Window的唯一实现类是PhoneWindow?你可以从第一篇关于Android中View事件分发的文章中找到答案。再看PhoneWindow的setContentView方法;@OverridepublicvoidsetContentView(intlayoutResID){//注意:FEATURE_CONTENT_TRANSITIONS可能在安装窗口的过程中被设置//decor,当主题属性等被结晶时。在此之前不要检查功能//。if(mContentParent==null){//1、installDecor();}elseif(!hasFeature(FEATURE_CONTENT_TRANSITIONS)){mContentParent。删除所有视图();}if(hasFeature(FEATURE_CONTENT_TRANSITIONS)){鳍alScenenewScene=Scene.getSceneForLayout(mContentParent,layoutResID,getContext());过渡到(新场景);}else{//2,mLayoutInflater.inflate(layoutResID,mContentParent);}mContentParent.requestApplyInsets();最终Window.Callbackcb=getCallback();if(cb!=null&&!isDestroyed()){//3、cb.onContentChanged();}//4、mContentParentExplicitlySet=true;}注3表示回调Activity的onContentChanged方法;注4表示布局已设置。当mContentParentExplicitlySet=false时,PhoneWindow的requestFeature方法已经被调用。当mContentParentExplicitlySet=true时,不能再调用PhoneWindow的requestFeature方法。我们看看PhoneWindow的requestFeature方法;@OverridepublicbooleanrequestFeature(intfeatureId){if(mContentParentExplicitlySet){thrownewAndroidRuntimeException("在添加内容之前必须调用requestFeature()");}......}上面说到注1的意思是实例化DecorView并安装,我们来看看installDecor方法的实现主体实施;privatevoidinstallDecor(){mForceDecorInstall=false;if(mDecor==null){//5,mDecor=generateDecor(-1);......}else{mDecor.setWindow(this);}if(mContentParent==null){//6,mContentParent=generateLayout(mDecor);......}}注5中的mDecor是一个DecorView对象,也是我们Activity的最顶层视图,它的父类是FrameLayout,我们来看看PhoneWindow的generateDecor方法是如何创建一个DecorView对象的;protectedDecorViewgenerateDecor(intfeatureId){......returnnewDecorView(context,featureId,this,getAttributes());}直接新建一个DecorView并返回,我们回到注释6中的代码installDecor方法,即PhoneWindow的generateLayout方法;protectedViewGroupgenerateLayout(DecorViewdecor){//7、TypedArraya=getWindowStyle();…//8.mIsFloating=a.getBoolean(R.styleable.Window_windowIsFloating,false);intflagsToUpdate=(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR)&(~getForcedWindowFlags());如果(mIsFloating){setLayout(WRAP_CONTENT,WRAP_CONTENT);setFlags(0,flagsToUpdate);}else{setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR,flagsToUpdate);}//9、if(a.getBoolean(R.styleable.Window_windowNoTitle,false)){requestFeature(FEATURE_NO_TITLE);}elseif(a.getBoolean(R.styleable.Window_windowActionBar,false)){//如果没有标题,则不允许使用操作栏。请求功能(FEATURE_ACTION_BAR);}......//10、mIsTranslucent=a.getBoolean(R.styleable.Window_windowIsTranslucent,false);......//11、intlayoutResource;//12、intfeatures=getLocalFeatures();//System.out.println("Features:0x"+Integer.toHexString(features));if((features&(1<
