前言
前俩篇文章咱们聊了setContentView的源码,已及如何理解Window。
简单回顾一下:结合第一篇文章setContentView的源码,我们知道View是通过DecorView添加到Window中。此后第二篇文章,我们又了解到Activity很多能力是由Window通过WindowManager管理,View的绘制就是其中之一。
因此对于我们的View来说,很大程度上和Activity是没有关系的,全依赖于Window/WindowManager去管理。
今天咱们通过requestLayout来彻底看一看,我们的View在众多概念(Window、DecorView、ViewRootImpl)中扮演了什么样的角色。
正文
一、前置准备
这部分先让我们了解一下View树的建立,看一看我们界面上的View们是怎样串联起来的。
1.1、回顾Window存在的意义
上篇文章我们提到过Activity的attach()方法,从源码可以看到。attach中会实例化PhoneWindow,并拿到WindowManager设置到自身当中。
final void attach(...) { ... mWindow = new PhoneWindow(this); mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); if (mParent != null) { mWindow.setContainer(mParent.getWindow()); } mWindowManager = mWindow.getWindowManager(); ...}
因此我们就可以明确Activity中通过WindowManager创建了一个Window实例。
1.2、搞清Window,ViewRootImpl,DecorView的关系
不知道大家如何理解这3个类。不过无所谓了,咱们来在这里重新过一下~
首先,第二篇文章咱们已经明确了Activity的attach()中会初始化了PhoneWindow;并且第一篇文章中我们捋了DecorView的初始化以及我们setContentView的内容如何被初始化,其中PhoneWindow通过installDecor(