今天就跟大家聊聊有关深入浅析Android中DecorView与ViewRootImpl的区别,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
<强>从setContentView说起强>
一般地,我们在活动中,会在onCreate()方法中写下这样一句:
显然,这是为活动设置一个我们定义好主要的。xml布的局,我们跟踪一下源码,看看这个方法是怎样做的,活动# setContentView:
最终无效连接(上下文语境,ActivityThread aThread, 仪表instr、内部令牌,int鉴别, 应用程序应用程序、目的意图ActivityInfo信息, CharSequence进行标题、活动家长,字符串id, NonConfigurationInstances lastNonConfigurationInstances, 配置配置、字符串引用IVoiceInteractor voiceInteractor) { … mWindow=new PhoneWindow(这个); … }
我们只看关键部分,这里实例化了PhoneWindow类,由此得知,PhoneWindow是窗口的实现类,那么我们在PhoneWindow类里面找到它的setContentView方法,看看它又实现了什么,PhoneWindow # setContentView:
@Override 公共空间setContentView (int layoutResID) {//注意:FEATURE_CONTENT_TRANSITIONS可能设置的过程中安装窗口//装饰,当主题属性之类的菜。不检查这个功能吗//在此之前发生。 如果(mContentParent==null) {//1 installDecor (); }else if (! hasFeature (FEATURE_CONTENT_TRANSITIONS)) { mContentParent.removeAllViews (); } 如果(hasFeature (FEATURE_CONTENT_TRANSITIONS)) { 最后一幕场景newScene=etSceneForLayout (mContentParent layoutResID, getContext ()); transitionTo (newScene); 其他}{ mLayoutInflater。充气(layoutResID mContentParent);//2 } 最后回调cb=getCallback (); 如果(cb !=零,,! isDestroyed ()) { cb.onContentChanged (); } }
首先判断了mContentParent是否为null,如果为空则执行installDecor()方法,那么这个mContentParent又是什么呢?我们看一下它的注释:
//这是放置视图窗口的内容。它不是//mDecor本身,或一个孩子mDecor内容去哪里。 私人ViewGroup mContentParent;
它是一个ViewGroup类型,结合②号代码处,可以得知,这个mContentParent是我们设置的布局(即main。xml)的父布局。注释还提到了,这个mContentParent是mDecor本身或者是mDecor的一个子元素,这句话什么意思呢?这里先留一个疑问,下面会解释。
这里先梳理一下以上的内容:活动通过PhoneWindow的setContentView方法来设置布的局,而设置布局之前,会先判断是否存在mContentParent,而我们设置的布局文件则是mContentParent的子元素。
<强>创建DecorView 强>
接着上面提到的installDecor()方法,我们看看它的源码,PhoneWindow # installDecor:
保护DecorView generateDecor () { 返回新DecorView (getContext (), 1); }
可以看的出,这里实例化了DecorView,而DecorView则是PhoneWindow类的一个内部类,继承于FrameLayout,由此可知它也是一个ViewGroup。
那么,DecroView到底充当了什么样的角色呢?
其实,DecorView是整个ViewTree的最顶层来看,它是一个FrameLayout布的局,代表了整个应用的界面。在该布局下面,有标题视图和内容视图这两个子元素,而内容视图则是上面提到的mContentParent。我们接着看②号代码,PhoneWindow # generateLayout方法