ViewRootImpl
路径:core/java/android/view/ViewRootImpl.java
官方解释:The top of a view hierarchy, implementing the needed protocol between View and the WindowManager.
就是说ViewRootImpl是View树的树根,实现了View与WindowManager之间的通信协议,具体的实现详情在WindowManagerGlobal这个类中。
参考网址:http://www.voidcn.com/article/p-ezcahzdf-qh.html
在Activity#handleResumeActivity()中,会将Activity所关联的PhoneWindow对象中的DecorView传递给ViewRootImpl#setView()中。而由ViewRootImpl负责对该View进行测量、布局与绘制,同时ViewRootImpl会与WMS交互,将Activity的UI给展示出来。
ViewRootImpl主要作用我的总结为如下:
(1)将DecorView传递给WindowManagerSerive。
(2)完成View的绘制过程,包括measure、layout、draw过程。
(3)向DecorView分发收到的用户发起的event事件,如按键,触屏等事件。
PhoneWindow、DecorView
路径:core/java/com/android/internal/policy/PhoneWindow.java
// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
参考文章:https://blog.csdn.net/zhangcanyan/article/details/52973127
setContentView(resId),经过一系列的操作,最终resId代表的view会被作为子view添加到DecorView中
WindowManagerGlobal
路径:core/java/android/view/WindowManagerGlobal.java
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
View的绘制原理
View树的绘图流程是在ViewRootImpl类的performTraversals()方法中,对于view的measure、layout、draw也分别是在这个方法中调用的,总体来说一个view显示到屏幕上分为三个阶段
- measure阶段,对于一个view来说需要通过measure来确定自己的宽高,而对于viewgroup来说需要循环遍历子view,分别完成子view的measure,最终确定viewgroup的大小,measure阶段有个类比较重要MeasureSpec,这个类封装了size和mode,在进行measure的时候需要根据父容器的MeasureSpec和自己的layoutparams来确定自己的MeasureSpec
- layout阶段,viewgroup用来确定子元素的位置,当viewgroup的位置被确定后,它在onlayout方法中会遍历所有的子元素并调用其layout方法,然后在子view的layout方法中调用子view的onlayout方法确定子view的位置。
- draw阶段,将view绘制到屏幕上
绘制一般分为几步
a.绘制背景background
b.绘制自己,就是调用onDraw
c.绘制children,就是调用dispatchDraw
d.绘制装饰,比如说滚动条(scrollbars)