1、View和ViewRoot

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

咱们看下下面的布局代码:

   
 上面的布局代码只是一份任意的布局代码,这里主要看下其结构,该布局代码的View结构可以描如下:                 在该布局中,ViewRoot中的mView成员变量指向的就是它所管理的View树的根,即上图中的LinearLayout:test元素。ViewRoot的核心任务就是与WindowManagerService进行通信。          2、Activity和Window的关系          我们知道Activity是支持显示UI的,那么它是否直接管理view树或者ViewRoot呢?答案时否定的,Activity并没有与这两者产生直接的联系,因为这中间还有一个被称为“Window”的对象。大家可以在Activity的源码中找到如下代码:private Window mWindow;          Window的字面意思是"窗口",这很好地解释了它存在的意义。Window是基类,根据不同的产品可以衍生出不同的子类——具体则是由系统在Activity.attach中调用PolicyManager.makeNewWindow决定的,目前版本的Android系统默认生成的都是PhoneWindo。          3、Window和WindowManagerImpl的关系          在Android源码中以“Window”开头的类有不少,如Window,WindowManager,WindowManagerImpl等,为什么需要这么多相似的类呢?          先来看Window,它是面向Activity的,表示"UI界面的外框";而“框里面”具体的东西包括布局和内容等,是由具体的Window子类,如PhoneWindow来规划的。          Window的另一层含义是要与WindowManagerService进行通信,但它并没有直接在自身实现这一功能。原因是:一个应用程序中很可能存在多个Window。如果它们都单独与WMS通信,那么既浪费资源,又会造成管理的混乱。换句话说,它们需要统一的管理。于是就有了WindowManager,它作为Window的成员变量mWindowManager存在。这个WindowManager是一个接口类,其真正的实现是WindowManagerImpl,后者同时也是整个应用程序中所有Window的管理者。因而WindowManager与WindowManagerImpl的关系有点类似于“地方与中央”:地方为实施中央的“政策”提供了一个接口,然后汇总到中央进行管理。          在Window的源码中与mWindowMager有关的代码有如下几句:private WindowManager mWindowManager;          mWindowManager     = (( WindowManagerImpl    )    wm    ). createLocalWindowManager    (    this    );                   
 public WindowManager getWindowManager() {
         return mWindowManager;
     }

然后我们去WindowManagerImpl的代码中去查看createLocalWindowManager方法的代码,代码如下:
 
 public WindowManagerImpl createLocalWidnowManager(Window parentWindow) {
        return new WindowManagerImpl(mDisplayparentWindow);
    }
从这几处代码,大家可以看到Window类中的mWindowManger引用的其实是WindowManagerImpl的实例。
4、ViewRoot和WindowManagerImpl的关系
在早期的系统版本中,WindowManagerImpl在每个进程中只有一个实例。调用它必须使用如下语句:WindowManagerImpl.getDefault();
在WindowMangerImpl内部,存在3个全局变量:(下图中的源码是2.3.5中的)
它们分别用于表示View树的根节点、ViewRoot以及Window的属性。由此也可以看出,一个进程中不仅有一个ViewRoot;而Activity与ViewRoot则是一对一的关系。自Android4.3开始对此做了修改,WindowManagerImpl不再直接存储上述三个数组变量,而是由一个称为“WindowMangerGlobal”的类统一管理。 5、ViewRoot和WindowManagerService的关系 每一个ViewRootImpl内部,都有一个全局变量 static IWindowSession sWindowSession; 这个变量用于ViewRoot到WMS的连接,它是ViewRoot利用WMS的openSession()接口来创建得到的。在此基础上,ViewRoot也会通过IWindowSession.add()方法提供一个IWindow对象——从而让WMS也可以通过这个IBinder对象来与ViewRoot进行双向通信。 这里突然间冒出一个ViewRootImpl类,其实ViewRoot与ViewRootImpl的功能是一样的,只不过是Android不同版本的不同称呼。不信看下图:

既然说到这个图了,那么就在这里给大家推荐一个可以在线看Android源码的网站: http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/ 其实每个Application都有一个ActivityThread主线程以及mActivities全局变量,后者记录了运行在应用程序中的所有Activity对象。一个Activity对应唯一的WindowManager以及ViewRootImpl。WindowManagerGlobal作为全局管理者,其内部的mRoots和mViews记录了Activity的ViewRootImpl和View树的顶层元素。ViewRootImpl的另一个重要角色就是负责与WMS通信。从ViewRootImpl到WMS间的通信利用的是IWindowSession,而反方向则是由IWindow来完成的。 最后补充说明一点:Activity中有一个成员变量mWindow,mWindow里面有一个成员变量mWindowManager,而mWindowManager是WindowMangerImpl类实例的引用,另外WindowMangerImpl里面包含ViewRoot(不管老版本中直接包含,还是新版本中间接包含)。 本篇博文只是为了记录我对于ViewRoot以及与ViewRoot相关的一些概念的了解。 转载请注明出处: http://blog.csdn.net/android_jiangjun/article/details/45798221

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. Android(安卓)为点击事件添加震动效果
  3. Android(安卓)M 动态权限获取
  4. Android(安卓)NDK开发两部曲(一)之初识篇(JNI通识与NDK配置)
  5. Flutter混合开发踩坑指北
  6. android AIDL RPC 机制
  7. Android(安卓)中的拿来主义(编译,反编译,AXMLPrinter2,smali,baksm
  8. Lan给您分享的岗位信息(Android)
  9. Ophone和Android的关系如何?

随机推荐

  1. Nginx 的动态变量指令map 的使用
  2. 网页设计与制作
  3. 数据分析必备5个EXCEL技巧,数据再多也不怕
  4. 开课啦 dubbo-go 微服务升级实战
  5. 你有一份经典SQL语句大全,请注意查收!!!
  6. python入门教程14-01 (python语法入门之py
  7. 【一点一滴,成材之基!】案例:企业安全项目--
  8. kubernetes常用控制器之Job和CronJob
  9. kubernetes其他控制器之PodDisruptionBud
  10. 网页