setContentView方法工作流程:
setContentView方法的具体实现是在PhoneWindow类中,主要通过如下几个步骤完成xml布局资源文件或View的加载。
setContentView步骤详解: Android源码分析-setContentView加载布局流程_RaoMeng1995的博客-CSDN博客
-
第一步:若是首次使用setContentView方法,则先创建一个DecorView对象mDecor,该对象是整个Activity窗口的根视图;然后根据程序中选择的Activity的Theme/Style等属性值为窗口添加布局属性和相应的修饰文件,并通过findViewById方法获取对应的根布局文件添加到mDecor中,也就是说,第一次使用该方法时会将Activity显示区域进行初始化;若不是第一次使用该方法,则之前已完成初始化过程并获得了mDecor和mContentParent对象,则只需要将之前添加到mContentParent区域的Views移除,空出该区域重新进行布局即可,简而言之,就是对mContentParent区域进行刷新; -
第二步:通过res.getLayout(resource)方法对布局资源进行了XML解析,将布局资源解析成XmlResourceParser对象,然后调用同名的inflate方法进行下一步操作。、 -
第三步:循环上面解析好的布局资源XmlResourceParser对象,取出布局的根节点,调用createViewFromTag方法先生成根节点View。然后再调用rInflateChildren方法递归的生成整个布局View树。最后将生成的View树添加到DecorView的root根布局上。 -
第四步:调用mFactory2的onCreateView或createView方法来生成View对象,这里的onCreateView方法中会为View的节点名添加"android.view."前缀,然后再调用createView方法生成View对象。做这一步操作是因为createView方法是通过反射生成的对象,所以需要完整的包名+类名,而Android系统自带的View都是放在android.view包下。createView中先是通过ClassLoader的反射机制,获取到对应的Class对象,然后获取到它的构造方法。最后通过构造方法实例化这个View对象并返回。 -
第五步:首先先调用上面已经分析过的createViewFromTag方法生成当前的节点View对象,然后这里会把当前这个View作为父节点递归调用rInflateChildren方法,如果当前View有子节点,就会递归的生成子节点并调用addView方法层层的插入对应的父节点。最终就会生成一个完整的View树,整体的页面布局也就显现出来了。
|