Android中与ViewRoot相关的一些概念

1、View和ViewRoot

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

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

<pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
	 android:id="@+id/test"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
	<Button
	    android:id="@+id/start_service"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:text="Start Service"
	    />
	<Button
	    android:id="@+id/stop_service"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:text="Stop Service"
	    />
	<Button
	    android:id="@+id/bind_service"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:text="Bind Service"
	    />
	<Button
	    android:id="@+id/unbind_service"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:text="Unbind Service"
	    />

</LinearLayout>


上面的布局代码只是一份任意的布局代码,这里主要看下其结构,该布局代码的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(mDisplay, parentWindow);

    }

从这几处代码,大家可以看到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

时间: 2024-08-04 21:45:22

Android中与ViewRoot相关的一些概念的相关文章

Android中bitmap的相关处理

加载大图片 Options options=new Options(); options.inJustDecodeBounds=true;//不加载图片,只加载文件信息 //加载图片,获取到配置信息 BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/a.jpg",options); int width=options.outWidth;//获取到图片的真是宽度 int height=options.

Android中的style相关属性

android中的style属性值 Android平台定义的主题样式: android:theme="@android:style/Theme.Dialog" // 将一个Activity显示为对话框模式 android:theme="@android:style/Theme.NoTitleBar" // 不显示应用程序标题栏 android:theme="@android:style/Theme.NoTitleBar.Fullscreen" /

Android中WebView的相关使用

近期做的项目中,遇到个非常棘手的问题: 客户给我的数据是有限制的,因此,在返回某条详细页面内容的时候,他仅仅能给我一个html片段,里面包括 文字,图片以及附件的下载地址.假设网页模版规范的爱比較好说,可是他给我的数据中,不确定的因素非常多: 比方 可能没有图片,图片和文字穿插在一起,最为重要的是html便签他的嵌套层次和标签个数都是不确定的. 假设我採用解析html提取内容出来的话,预计就掉进坑里了....... 但实际情况中,打算server先将客户代码的标签属性删除,仅仅剩骨头,但结果还是

Android中图片处理相关问题

在Android的开发中,我们经常回去处理一些图片相关的问题,比如当加载图片到内存中产生的OOM(OutOfMemory)异常.图片加载到内存中占多大内存的问题.jpg png两种常见的图片的原理及区别. 图片加载到内存所占内存大小的问题 在讲OOM异常前需要对图片的加载有所了解,所以在这里就先介绍图片加载的问题.  图片加载到内存中的大小,不是直接由图片的存储大小来决定的.比如一个10k大小的png格式的图片加载到内存可能就不止10k了.那应该怎么计算呢?      图片加载到内存中的大小=图

家庭记账本app进度之android中AlertDialog的相关应用以及对日期时间的相关操作(应用alertdialog使用的谈话框)

对于AlertDialog的相关知识: 1.创建构造器AlertDialog.Builder的对象:    2.通过构造器对象调用setTitle.setMessage.setIcon等方法构造对话框的标题.信息和图标等内容:    3.根据需要调用setPositive/Negative/NeutralButton()方法设置正面按钮.负面按钮和中立按钮:    4.调用构造器对象的create方法创建AlertDialog对象:    5.AlertDialog对象调用show方法,让对话框

Android中Intent的相关用法

Intent第一个用法便是用它来进行活动之间的跳转 新建一个SecondActivity活动,并为之新建一个second_layout.XML布局文件,也创建一个Button按钮,名字为Button 2.然后在AndroidManifest.XML中进行注册. 接下来在FirstAcitivity中重写按钮点击时间 按钮点击事件首先要新建一个按钮监听器,然后在监听器中重写onClick方法. 而onClick方法中便是Intent如何显示跳转活动,即明确规定跳转到哪个活动.先新建一个intent

android中与Adapter相关的控件----Spinner&amp;AutoCompleteTextView

Spinner(列表选项框) & AutoCompleteTextView(自动完成文本框) 一.列表选项框核心属性 android:dropDownHorizontalOffset设置列表框的水平偏移距离 android:dropDownVerticalOffset设置列表框的水平竖直距离 android:dropDownSelector设置列表被选中时背景 android:dropDownWidth设置下拉列表框的宽度 android:gravity设置里面组件的对其方式 android:p

Android中显示和隐式Intent的使用

显示启动activity                                                                                                                   这个很简单,下面是代码示例:为了看着方便,所以就把layout直接截图了,里面的代码只是一些简单的布局.activity_login.xml: activity_main.xml: 下面是Manifest.xml中的代码 1 <?xml vers

Android中自定义视图View之---前奏篇

前言 好长时间没写blog了,心里感觉有点空荡荡的,今天有时间就来写一个关于自定义视图的的blog吧.关于这篇blog,网上已经有很多案例了,其实没什么难度的.但是我们在开发的过程中有时候会用到一些自定义的View以达到我们所需要的效果.其实网上的很多案例我们看完之后,发现这部分没什么难度的,我总结了两点: 1.准备纸和笔,计算坐标 2.在onDraw方法中开始画图,invalidate方法刷新,onTouchEvent方法监听触摸事件 对于绘图相关的知识,之前在弄JavaSE相关的知识的时候,