ActivityThread中,当Activity对象被创建完毕后,会将DecorView添加到Window中,同时会创建ViewRootImpl对象,并将ViewRootImpl对象和DecorView建立关联。
- Activity的UI框架
- Activity上Window的创建关联流程
- 基础知识
- view的绘制
Activity的UI框架
Activity上Window的创建关联流程
基础知识
MeasureSpec
32位整数,高2位表示测量模式SpecMode,低30位表示某种测量模式下的规格大小SpecSize。
SpecMode
- UNSPECIFIED:不指定测量模式,父视图没有限制子视图的大小,子视图可以是想要的任何尺寸。
- EXACTLY:精确测量模式,这种模式下View的测量值就是SpecSize。
- AT_MOST:最大值模式,wrap_content子视图的尺寸可以是不超过父视图允许的最大尺寸的任何尺寸。
LayoutParams
View的绘制
绘制从根视图ViewRoot的performTraversals()方法开始,从上到下遍历整个视图树,View控件负责绘制自己,而ViewGroup还需通知自己的子View进行绘制操作。
- 测量(Measure):ViewGroup[measureChildren-measureChild]View[measure-onMeasure],如果子View没有重写onMeasure,则默认会调用getDefaultSize来获得View的宽高。setMeasureDimension
- 布局(Layout):View[layut-onLayout]
- 绘制(Draw):ViewRootImpl[performDraw-draw]
注意:View的measure过程和Activity的生命周期方法不是同步执行的,因此无法保证Activity执行了onCreate、onStart、onResume时某个View已经测量完成,获得的宽/高就是0。解决方案如下:
- onWindowFocusChanged,造成频繁调用
- view.post(runnable)
- ViewTreeObserver-addOnGlobalLayoutListener
- view.measure(int widthMeasureSpec, int heightMeasureSpec)手动对View进行measure得到宽与高。