参考一些网上的资料以及个人的理解来介绍 Android view的绘制流程
1.上图是一个Activity窗口结构图
当activity创建的同时也会关联一个window,Window即窗口,窗口是一个宏观的思想,它是屏幕上用于绘制各种UI元素及响应用户输入事件的一个矩形区域。android.view.Window是一个抽象类。PhoneWindow这个类是Framework为我们提供的android.view.Window的具体实现。我们平时调用setContentView()方法设置Activity的用户界面时,实际上就完成了对所关联的PhoneWindow的ViewTree的设置。
2.setContentView()
这个方法只是完成了Activity的ContentView的填充,而并没有执行View的绘制流程。
3.ViewRoot
View的绘制是由ViewRoot来负责的。当Activity启动时DecorView关联了ViewRoot对象,这种关联关系是由WindowManager来维护的。
4.View绘制的起点
当建立好了decorView与ViewRoot的关联后,ViewRoot类的requestLayout()方法会被调用,以完成应用程序用户界面的初次布局。实际被调用的是ViewRootImpl类的requestLayout()方法,这个方法的源码如下:
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
// 检查发起布局请求的线程是否为主线程
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
上面的方法中调用了scheduleTraversals()方法来调度一次完成的绘制流程,该方法会向主线程发送一个“遍历”消息,最终会导致ViewRootImpl的performTraversals()方法被调用。下面,我们以performTraversals()为起点,来分析View的整个绘制流程。
三个阶段
measure: 判断是否需要重新计算View的大小,需要的话则计算;
layout: 判断是否需要重新计算View的位置,需要的话则计算;
draw: 判断是否需要重新绘制View,需要的话则重绘制。
这三个子阶段可以用下图来描述: