View绘制流程的入口是WindowManager.add(decor, l),从Activity的创建开始分析,具体流程如下:
Activity.onCreate()
setContentView(R.layout.activity_main);
Window.setContentView(layoutResID);
ActivityThread.handleResumeActivity()
ActivityThread.performResumeActivity()
Activity.onResume()
wm.addView(decor, l); //把DecorView加载到WindowManager,这时才开始View的绘制
WindowManangerImpl.addView()
mGlobal.addView(view, params, mDisplay, mParentWindow); //WindowManagerGlobal
root.setView(view, wparams, panelParentView); //ViewRootImpl
ViewRootImpl.requestLayout()
ViewRootImpl.scheduleTraversals()
doTraversal()
performTraversals() //这个方法里就开始测量、布局、绘制了
详细的绘制流程,可参考 invalidate()源码分析
可以看到,在Activity.onResume()执行完后,才开始View的绘制流程,这也就解释了在Activity的onCreate()或onResume()方法中,是获取不到控件的宽和高的。