View的绘制流程(一):Activity.setContentView()背后发生了什么

        熟悉View的绘制流程对于熟练掌握自定义View和性能调优,是至关重要的一环。对于日常工作中的一些布局嵌套出现的问题和出现问题的原因能够快速的定位。比如在ListView还流行时,ScrollView嵌套ListView高度只显示一个item的问题。这个问题是由于ScrollView传递给ListView的测量模式引起的。这个问题也是View的绘制流程中的一个环节出了问题。言归正传,熟悉View的绘制流程涉及的代码和篇幅会比较大,再三斟酌,应该分几篇来讲。希望我写的流程能够让大家看的清晰。如果有环节出现纰漏或者错误,欢迎指出和探讨。下面我们就从setContentView()方法开始吧!


        下面的分析是基于SDK28 (Android9.0)版本的,不同版本可能会有所不同,但大体差不多。Activity.setContentView()方法调用的是getWindow().setContentView()。

让我们来看看getWindow(),Window类是一个抽象类,所以让我们来看下mWindow的赋值过程。我们可以看到mWindow在attach()方法中被赋值,我们就知道mWindow实际就是PhoneWindow,接下来我们看下PhoneWindow.setContentView()方法。

当Activity第一次被打开时,mContentParent==null,必定会走installDecor()。让我们来看下installDecor()方法。

我们可以看到mDecor是new出来的DecorView。DecorView继承自FrameLayout,所以也是一个ViewGroup。并在构造方法setWindow(),将PhoneWindow赋值给自己的成员变量。

接下来让我们看下mContentParent的赋值过程generateLayout(mDecor)方法

我们可以看到在generateLayout方法中有很多的layout,这些layout里面都有一个id为content的FrameLayout 。并且mDecor会通过onResourcesLoaded()方法将这些layout填充进来,并简单设置了布局的参数。然后赋值给了mContentParent.走到这里,我们的setContentView()方法就基本走完了。


总结

        Activity.setContentView是一个初始化布局的过程,涉及PhoneWindow、DecorView和Android自带布局的初始化过程。通过setContentView设置进去的布局,会加载到DecorView下面的Android自带布局id为content的FrameLayout下。

你可能感兴趣的:(View的绘制流程(一):Activity.setContentView()背后发生了什么)