Activity窗口绘制和Window、PhoneWindow、DecorView、setContentView的执行顺序

-- DecorView构成

https://img-blog.csdnimg.cn/20181117164446310.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NoYXJlVXM=,size_16,color_FFFFFF,t_70

https://img-blog.csdnimg.cn/20181117215208987.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NoYXJlVXM=,size_16,color_FFFFFF,t_70

-- Window、PhoneWindow、DecorView、setContentView

  Window窗口布局 --- DecorView浅析- https://www.cnblogs.com/yogin/p/4061050.html
 Activity onCreate()中调用setContentView(R.layout.custom_layout)来实现想要的页面布局,我们知道,页面都是依附在窗口之上的,而DecorView即是窗口最顶层的视图。Android frameworks中,与窗口视图处理相关的类,主要是Window及其实现类PhoneWindow。
public class PhoneWindow extends Window implements MenuBuilder.Callback {
  //...
  //窗口顶层View
   private DecorView mDecor;  
  //所有自定义View的根View, id="@android:id/content"
   private ViewGroup mContentParent;
}

  Window-> PhoneWindow-> DecorView-> Activity;
  Activity#setContentView- Activity#attach- PhoneWindow#setContentView- PhoneWindow#installDecor- PhoneWindow#generateDecor(DecorView)- PhoneWindow#generateLayout- DecorView添加至Window- WindowManagerImpl#addView- WindowManagerGlobal#addView- ViewRootImpl#setView;

 DecorView其实是PhoneWindow中的一个内部类,本质上也是一个View,其只是扩展了FrameLayout的实现
 private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {}
 DecorView是整个ViewTree的最顶层View,它是一个FrameLayout布局,代表了整个应用的界面。通过setContentView方法,创建了DecorView和加载了我们提供的布局,但是这时,我们的View还是不可见的,因为我们仅仅是加载了布局,并没有对View进行任何的测量、布局、绘制工作。在View进行测量流程之前,还要进行一个步骤,那就是把DecorView添加至window中,然后经过一系列过程触发ViewRootImpl#performTraversals方法,在该方法内部会正式开始测量、布局、绘制这三大流程。
  将DecorView添加至Window;
每一个Activity组件都有一个关联的Window对象,用来描述一个应用程序窗口。每一个应用程序窗口内部又包含有一个View对象,用来描述应用程序窗口的视图。上文分析了创建DecorView的过程,现在则要把DecorView添加到Window对象中。
 最后通过WMS调用ViewRootImpl#performTraverals方法开始View的测量、布局、绘制流程
  DecorView是activity窗口的根视图。每个activity都对应一个窗口window,这个窗口是PhoneWindow的实例,PhoneWindow对应的布局是DecirView,是一个FrameLayout,DecorView内部又分为两部分,一部分是ActionBar,另一部分是ContentParent,即activity在setContentView对应的布局。

  事件分发机制:down move up; View的绘制:测量、布局、绘制流程;

  一、DecorView为整个Window界面的最顶层View。 二、DecorView只有一个子元素为LinearLayout。代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域。 三、LinearLayout里有两个FrameLayout子元素。
DecorView是怎么显示出来的?
 每一个Activity都包含一个Window对象,Window对象通常由PhoneWindow实现;
PhoneWindow:将Decoriew设置为整个应用窗口的根View。是Window的实现类。它是Android中的最基本的窗口系统,每个Activity 均会创建一个PhoneWindow对象,是Activity和整个View系统交互的接口。
DecorView:顶层视图,将要显示的具体内容呈现在PhoneWindow上. DecorView是当前Activity所有View的祖先,它并不会向用户呈现任何东西,它主要有如下几个功能,可能不全:
A. Dispatch ViewRoot分发来的key、touch、trackball等外部事件;
B. DecorView有一个直接的子View,我们称之为System Layout,这个View是从系统的Layout.xml中解析出的,它包含当前UI的风格,如是否带title、是否带process bar等。可以称这些属性为Window decorations。  
C. 作为PhoneWindow与ViewRoot之间的桥梁,ViewRoot通过DecorView设置窗口属性。//可以这样获取 View view = getWindow().getDecorView();
DecorView只有一个子元素为LinearLayout。代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域。DecorView里面TitleView:标题,可以设置requestWindowFeature(Window.FEATURE_NO_TITLE)取消掉ContentView:是一个id为content的FrameLayout。我们平常在Activity使用的setContentView就是设置在这里,也就是在FrameLayout上。

 Window是一个抽象基类,它提供了一系列窗口的方法,比如设置背景,标题等等,而它的唯一实现类则是PhoneWindow。在PhoneWindow里面,出现了成员变量DecorView的而这里,DecorView则是PhoneWindow里面的一个内部类,它是继承与FrameLayout。

 Window是一个抽象类,提供了各种窗口操作的方法,比如设置背景标题ContentView等等 
PhoneWindow则是Window的唯一实现类,它里面实现了各种添加背景主题ContentView的方法,内部通过DecorView来添加顶级视图; 每一个Activity上面都有一个Window,可以通过getWindow获取DecorView,顶级视图,继承与FramentLayout,setContentView则是添加在它里面的@id/content里; setContentView里面创建了DecorView,根据Theme,Feature添加了对应的布局文件当setContentView设置显示后会回调Activity的onContentChanged方法。

猜你喜欢

转载自blog.csdn.net/ShareUs/article/details/84190295