源码分析基于Android 7
应用程序中的View框架如图所示
1. View和ViewRoot
单单从名称看很容易让人产生误解,因为ViewRoot并不属于View树的一分子。源码上ViewRoot和View对象也没有继承关系。更准确说ViewRoot理解为View输的管理者,ViewRoot有一个mView成员变量指向View树的根。ViewRoot核心任务就是与WindowMangerService进行通信。
2. Activity和Window的关系
Activity是UI显示,但是Activity不直接管理View树或者ViewRoot,Activity与两者直接没有直接的联系,这中间由Window的对象关联。 源码上Activty类有一个成员变量mWdinow 。Window是一个基类,目前默认生成的都是PhoneWindow 。
3. Window和WindowMangaerImpl的关系
Window是面向Activity的,表示UI的外框,里内容和布局是由具体的Window子类,如PhoneWindow来规划。
Window的另一层含义是要与WindowManagerService进行通信,但它并没有直接在自身实现这一功能。原因:一个应用程序中很可能存在多个Window。如果都单独与WMS通信,那么浪费资源有导致管理混乱,所以需要统一管理,于是就有了WindowManger,它作为Window的成员变量mWindowManger存在。这个WindowManger是个接口类,真正实现是WindowManagerImpl,后者同时也是整个应用程序中所有Window的管理者。
4. ViewRoot和WindowMangerImpl的关系
在WindowManagerImpl内部中有三个全局变量
private View[] mViews;
private ViewRootImp[] mRoots ;
private WindowManger.LayoutParam[] mParams ;
分别是View树的根节点、ViewRoot以及Window的属性。
5. ViewRoot和WindowMangerService
每一个ViewRootImpl内部都有一个全局变量
static IWindowSession sWindowSession
这个变量用于ViewRoot到WMS的链接,它是ViewRoot利用WMS的opeSession()接口来创建得到的 。在此基础上,ViewRoot也会通过IWindowSession.add()方法提供一个IWindow对象-----从而让WMS也可以通过这个Binder对象来与ViewRoot进行双向通信。
一个应用都有一个ActivityThread主线程以及mActivitys全局变量,后者记录了运行在应用程序中的所有Activity对象。一个Activity对应唯一的WindowManger以及ViewRootImpl。 WindowMangerGlobal作为全局管理者,内部的mRoots与mViews记录了各Activity的ViewRootImpl和View树的顶层元素。ViewRootImpl的另一个重要角色就是负责与WMS进行通信。从ViewRootImpl到WMS间的通信利用的是IWindowSession,而反向则是有IWindow来完成。