概述
ViewRootImpl 是 Android 视图树中的顶级对象之一,负责管理窗口的创建、绘制和交互等任务。它的主要任务如下:
- 窗口管理:负责管理应用窗口的创建和销毁,计算窗口的大小和位置等属性;
- 视图绘制:负责将 View 树中的 View 绘制到屏幕上;
- 事件分发:负责监听和分发用户产生的 Input 事件,比如点击事件、触摸事件、实体按键事件等;
- 窗口焦点:负责管理窗口的焦点,确保正确的 View 获得焦点并处理相关事件;
- 动画处理:ViewRootImpl 与动画系统交互,处理视图的动画效果;
总的来说,ViewRootImpl 扮演着连接视图层和系统层的重要角色,它负责协调视图的显示和交互,并与系统其他部分进行交互,以确保应用程序能够正确地响应用户的操作。
重要方法
-
doTraversal,执行 View 树的遍历的起始入口,即测量(measure)、布局(layout)和绘制(draw)操作,一般在下述几种情况发生的时候被触发调用
- 触发重绘:比如视图内容发生变化或者调用了 invalidate 方法,会调用 doTraversal 方法来开始新一轮的遍历,以便更新视图的显示
- 处理输入事件:当用户进行交互操作(比如点击、滑动等)时,输入事件会传递给 ViewRootImpl,doTraversal 方法会被调用来处理这些事件,包括将事件分发给合适的视图处理
- 初始化视图:在窗口第一次创建或者内容发生变化时,ViewRootImpl 会调用 doTraversal 方法来初始化视图树,包括测量视图大小、布局视图位置以及绘制视图内容
-
performMeasure,执行 View 树测量(measure)过程,会对 View 树中的各个 View 进行测量,以确定 View 的大小。这个过程是由父 View 调用其子 View 的
measure()
方法来实现的。每个 View 都有自己的 measure() 方法,用于计算 View 的测量宽度和高度,并将测量结果保存在 View 的布局参数中,测量过程通常按照以下步骤进行:- 测量子视图:父视图调用每个子视图的
measure()
方法,以确定子视图的测量宽度和高度。这个过程会递归地遍历整个视图树 - 确定父视图的大小:根据子视图的测量结果,父视图决定自己的测量宽度和高度。这个过程通常由父视图的
onMeasure()
方法来实现 - 保存测量结果:父视图将自己的测量宽度和高度保存在自己的布局参数中,以便在布局过程中使用
- 传递测量要求:父视图将自己的测量要求传递给上一级的父视图,以便完成整个视图树的测量过程
- 测量子视图:父视图调用每个子视图的
-
performLayout,执行 View 树布局(layout)过程,确定View 在其父容器中的位置和大小,这个过程是由父容器调用其子 View 的
layout()
方法来实现的。每个 View 都有自己的layout()
方法,用于确定 View 的位置和大小,并将布局结果保存在 View 的位置参数中,布局过程通常按照以下步骤进行:- 布局子视图:父容器调用每个子 View 的
layout()
方法,以确定子 View 在父容器中的位置和大小。这个过程会递归地遍历整个 View 树 - 确定父容器的大小:根据子 View 的位置和大小,父容器决定自己的大小和位置。这个过程通常由父容器的
onLayout()
方法来实现 - 保存布局结果:父容器将自己的位置和大小保存在自己的位置参数中,以便在绘制过程中使用
- 传递布局要求:父容器将自己的布局要求传递给上一级的父容器,以便完成整个 View 树的布局过程
- 布局子视图:父容器调用每个子 View 的
-
performDraw,执行 View 树绘制(draw)过程,将 View 绘制到屏幕上,形成最终的图像。这个过程是由 View 类中的
draw()
方法来实现的。每个视图都有自己的draw()
方法,用于将自己的内容绘制到屏幕上。绘制过程通常按照以下步骤进行:- 绘制背景:首先,系统会绘制 View 的背景,即调用 View 的
drawBackground()
方法将背景绘制到屏幕上 - 绘制内容:接下来,系统会调用 View 的
onDraw()
方法来绘制 View 的内容,包括文字、图像等。开发者可以重写 View 的onDraw()
方法,自定义 View 的绘制内容 - 绘制子 View:如果当前 View 有子 View ,系统会递归地调用子 View 的
draw()
方法来绘制子 View 的内容 - 绘制前景:最后,系统会绘制 View 的前景,即调用 View 的
drawForeground()
方法将前景绘制到屏幕上
- 绘制背景:首先,系统会绘制 View 的背景,即调用 View 的
-
invalidate,通常不是直接调用的,而是通过 View 类的
invalidate()
方法触发的。当调用 View 对象的invalidate()
方法时,它会向 ViewRootImpl 发送一个无效(invalidate)请求,通知系统需要重新绘制相应的 View ,方法的作用是标记 View 或 View 组合需要被重绘,但它并不会立即触发重绘操作。相反,它会将一个重绘请求添加到消息队列中,在合适的时机由 ViewRootImpl 来处理 -
WindowInputEventReceiver,ViewRootImpl 的内部类,用于接收窗口的 Input 事件,从底层系统获取这些 Input事件,并将它们传递给 ViewRootImpl 进行处理