android ViewRoot学习,WindowManager和ViewRoot的关系

[size=medium][b]ViewRoot是GUI管理系统与GUI呈现系统之间的桥梁[/b][/size],根据ViewRoot的定义,我们发现[color=red]它并不是一个View类型,而是一个Handler。[/color]

它的主要作用如下:

[b]A. 向DecorView分发收到的用户发起的event事件,如按键,触屏,轨迹球等事件;[/b]

[color=red]B. 与WindowManagerService交互,完成整个Activity的GUI的绘制。[/color]

[size=medium][b]1、View和ViewRoot[/b][/size]
ViewRoot从名称上来理解似乎是“View树的根”,这很容易让人产生误解。
[color=red]因为ViewRoot并不属于View树的一份子。[/color]从源码实现上来看,ViewRoot和View对象并没有任何“血缘”关系,它既非View的子类,也非View的父类。
ViewRoot可以被理解为“[color=red]View树的管理者[/color]”——[b]它有一个mView成员变量,指向的是它所管理的View树的根。[/b]

[img]http://dl2.iteye.com/upload/attachment/0114/3948/b09f093f-8fa2-3be8-8c2e-6144ff270395.jpg[/img]

在该布局中,ViewRoot中的mView成员变量指向的就是它所管理的View树的根,即上图中的LinearLayout:test元素。[color=red]ViewRoot的核心任务就是与WindowManagerService进行通信。[/color]

[size=medium][b]2、Activity和Window的关系[/b][/size]
我们知道Activity是支持显示UI的,[color=blue]那么它是否直接管理view树或者ViewRoot呢?[/color]答案是[color=red]否定[/color]的,[b]Activity并没有与这两者产生直接的联系,因为这中间还有一个被称为“Window”的对象。[/b]
大家可以在Activity的源码中找到如下代码:[b]private Window mWindow;[/b] Window的字面意思是窗口,这很好地解释了它存在的意义。
Window是基类,根据不同的产品可以衍生出不同的子类——具体则是由系统在Activity.attach中调用PolicyManager.makeNewWindow决定的,目前版本的Android系统默认生成的都是[color=red]PhoneWindow[/color]。

[size=medium][b]3、Window和WindowManagerImpl的关系[/b][/size]
在Android源码中以“Window”开头的类有不少,[color=red]Window,WindowManager,WindowManagerImpl[/color]等,为什么需要这么多相似的类呢?
[color=red]先来看Window,它是面向Activity的,表示UI界面的外框;[/color]
而“框里面”具体的东西包括布局和内容等,是由具体的Window子类,如PhoneWindow来规划的。 [color=red]Window的另一层含义是要与WindowManagerService进行通信,但它并没有直接在自身实现这一功能。[/color]
原因是:[color=red]一个应用程序中很可能存在多个Window。[/color]
如果它们都单独与WMS通信,那么既浪费资源,又会造成管理的混乱。换句话说,[color=red]它们需要统一的管理。
于是就有了WindowManager,[/color]它作为Window的成员变量mWindowManager存在。[color=red]这个WindowManager是一个接口类,其真正的实现是WindowManagerImpl,后者同时也是整个应用程序中所有Window的管理者。[/color]因而WindowManager与WindowManagerImpl的关系有点类似于“地方与中央”:地方为实施中央的“政策”提供了一个接口,然后汇总到中央进行管理。 在Window的源码中与mWindowMager有关的代码有如下几句:
private WindowManager mWindowManager;
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);


[size=medium][b]4、ViewRoot和WindowManagerImpl的关系[/b][/size]
在早期的系统版本中,WindowManagerImpl在每个进程中只有一个实例。调用它必须使用如下语句:
WindowManagerImpl.getDefault();

在WindowMangerImpl内部,[color=red]存在3个全局变量[/color]:(下图中的源码是2.3.5中的)

它们分别用于表示[color=red]View树的根节点、ViewRoot以及Window的属性[/color]。由此也可以看出,[b]一个进程中不仅有一个ViewRoot;[/b]
[size=medium][color=red]而Activity与ViewRoot则是一对一的关系。[/color][/size]
自Android4.3开始对此做了修改,WindowManagerImpl不再直接存储上述三个数组变量,而是由一个称为“WindowMangerGlobal”的类统一管理。

[size=medium][b]5、ViewRoot和WindowManagerService的关系 [/b][/size]
每一个ViewRootImpl内部,都有一个全局变量
static IWindowSession sWindowSession; 

[color=red]这个变量用于ViewRoot到WMS的连接,它是ViewRoot利用WMS的openSession()方法来创建得到的。[/color]
在此基础上,ViewRoot也会通过IWindowSession.add()方法提供一个IWindow对象——从而让WMS也可以通过这个[color=red]IBinder对象来与ViewRoot进行双向通信[/color]。 这里突然间冒出一个ViewRootImpl类,其实ViewRoot与ViewRootImpl的功能是一样的,只不过是Android不同版本的不同称呼。

[b]其实每个Application都有一个ActivityThread主线程以及mActivities全局变量[/b],[color=red]后者记录了运行在应用程序中的所有Activity对象。[/color]

[color=red]一个Activity对应唯一的WindowManager以及ViewRootImpl。[/color]WindowManagerGlobal作为全局管理者,[color=red]其内部的mRoots和mViews记录了Activity的ViewRootImpl和View树的顶层元素。[/color]

[color=red]ViewRootImpl的另一个重要角色就是负责与WMS通信。[/color]从ViewRootImpl到WMS间的通信利用的是IWindowSession,而反方向则是由IWindow来完成的。
最后补充说明一点:[color=red]Activity中有一个成员变量mWindow,mWindow里面有一个成员变量mWindowManager,而mWindowManager是WindowMangerImpl类实例的引用,另外WindowMangerImpl里面包含ViewRoot。[/color]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值