android布局绘制的过程
android View 绘制工作原理
从Activity开始的setContentView开始
源码里面是:
public void setContentView(@LayoutResintlayoutResID)
{
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
所以继续追踪getWindow()
public Window getWindow()
{return mWindow;}
而mWindow又是啥时候来的呢?
//Activity
private Window mWindow;
final void attach(Contextcontext,ActivityThreadaThread,····)
{
attachBaseContext(context);
mFragments.attachHost(null/*parent*/);
mWindow=new PhoneWindow(this,window,activityConfigCallback);
}
由此可知activity中的attach这个方法得到mWindow,他其实就是PhoneWindow
继续刚才的setContentView
//PhoneWindow
@Override
public void setContentView(intlayoutResID)
{if(mContentParent==null){installDecor();}
所以当开启一个新页面时就是执行installDecor()
private void installDecor(){
if(mContentParent==null){mContentParent=generateLayout(mDecor);}
}
由此可知(DecorView)mDecor得到(ViewGroup)mContentParent;再由setContentView中的
mLayoutInflater.inflate(layoutResID,mContentParent);把布局文件弄上去啦!说到尾最终还是我们熟悉的inflate~多么熟悉的味道
总结:先看activity代码找到setcontentview是从这里设置进layoutid,再追踪代码,我看到getwindow()这个方法去设置,而getwindow又是从attach()得到的初始化对象phonewindow,这个phonewindow是继承于window抽象类,再跟踪代码后发现是phonewindow里面的installdecor方法中如果没有根布局的话generatelayout能得到我们最终的整个界面的根布局decorview,这个view就是我们activity界面的rootview,也是一个flamelayout。
值得注意的是,view的绘制过程是生命周期onresume开始的,因为activitythread中的H.handlerlaunchactivity中执行,也是viewrootimpl去实现。