【难度系数★★☆☆☆】我们为Activity设置页面内容,都是在onCreate()中调用setContentView(R.layout.layout_id)来实现的,那么setContentView是如何将一个layout.xml显示到手机屏幕上的呢?
在看这篇文章之前,可以先看我的这篇文章:startActivity流程分析 里面讲到了一个新启动的Activity的onCreate方法是如何被调用到的。
那么不废话直接放setContentView的流程图
看不清原图可以在这里看http://www.liyafeng.com/setContentView.html
通过上面的流程,我们可以知道:
- 一个xml是通过XmlParser来解析的,获取到的标签是通过反射的形式来创建一个View对象
- 一个PhoneWindow持有一个DecorView对象,这个DecorView继承自FrameLayout,而且是在setContentView的时候被创建
- 这个时候会在DecorView内部添加一个子布局,叫screen_simple.xml,这个布局就是title+content,这个content是一个FrameLayout,我们自己添加的视图就是添加到这里的
- 所有xml都被解析添加后,系统调用ViewRootImpl的doTraversal()方法来遍历View视图来进行measure、layout、draw
- 其实measure是测量view的宽高,如果是match_parent或者指定宽高,那么这个值就会被记录下来,如果是warp_content就会根据子view的测量来定。
- layout也会根据margin、padding这些参数,配合特定布局重写的onLayout方法来确定View的left、top、right、bottom这些参数
- 最后绘制,其实是从最顶层的DecorView的draw(canvas)开始,这个Canvas就一层层往下传,View就根据测量和布局的到的参数在画布的指定位置进行绘制,所以我们自定义控件就是重写onMeasure,onDraw,然后处理滑动事件,就能完成大部分常用的业务需求