天空看不见云,大火球在上面肆意发光,逼着毛孔慢慢渗出汗水。
我离开舒适区,跑出去面试了几次。
得到的最多的反馈是不够深入。
作为一个五年经验的安卓开发者,欠缺的还有很多。
前言
从一个view实例被创建,到展示到屏幕上,都经历了怎么样的一个流程?在安卓开发中,这似乎是一个基本的知识,应该被开发者清楚地认识明白,面试中也作为问题频频出现,然而我还是认识得不深刻。 Android View
的绘制流程 是View相关的核心知识点。我希望通过这篇文章学习并分享Android View绘制流程的始末。 并将其刻在脑子里。
目录
本文分为以下流程学习,阅读完本文将会学习到PhoneWindow
,WindowManger
,ViewRootImpl
,View
等关键类的联系和作用。对window窗体机制以及绘制流程有所了解。
- 流程图分析
- 了解view绘制流程
- 了解
setContentView
如何附加到内容到页面
关键类解释
Choreographer
:协调动画、输入和绘图的时间。Choreographer
从显示子系统接收定时脉冲(例如垂直同步),然后安排工作发生,作为渲染下一个显示帧的一部分。
一. 流程图分析
1.1 创建Activity到setContentView的窗口附加流程图
下图展示了window的创建到setContentView
之后的窗体view树变化情况
activity 设置布局流程
1.2 view绘制流程图
绘制流程图
二. view绘制流程
2.1 绘制流程分析
在我们调用requestLayout
和 invalidate
的时候,我们会让view刷新布局和绘制。所以从这两个方法入手,可以完整地走一遍绘制流程。 绘制动画等行为主要通过Choreographer
类协调。
- 调用
requestLayout
和invalidate
标记绘制和充布局信息 Choreographer
接受系统垂直同步等脉冲消息,在scheduleTraversals
方法中回调执行doTraversal
开始遍历view树。- 触发
ViewRootImpl#performTraversals
完成view树遍历- 如果
layoutRequested
为true,measureHierarchy
中测量mView
及其子view
- 需要的话,触发
ViewRootImpl#performLayout
完成布局 - 如果
view
没有隐藏且TreeObserver
中没有拦截绘制,就调用performDraw
,完成绘制- 计算dirty脏区域
- 从mSurface中 获取脏区域的canvas,交给view绘制
- 如果
2.2 ViewRootImpl
创建时机
从上面可以看到,所有的绘制和布局都是由ViewRootImpl#doTraversal
触发,然后对其持有的view树进行遍历绘制。所以一定要了解ViewRootImpl
和其持有的DecorView
的创建和关联时机。关键流程如下:
Activity#handleResume
的时候,调用WIndow