欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Android布局加载流程源码

程序员文章站 2022-04-29 09:18:56
一.首先看布局层次 看这么几张图我们会发现decorview里面包裹的内容可能会随着不同的情况而变化,但是在decor之前的层次关系都是固定的。即activity包裹phonewindow,phone...

一.首先看布局层次 看这么几张图

详解Android布局加载流程源码

详解Android布局加载流程源码

详解Android布局加载流程源码

详解Android布局加载流程源码

我们会发现decorview里面包裹的内容可能会随着不同的情况而变化,但是在decor之前的层次关系都是固定的。即activity包裹phonewindow,phonewindow包裹decorview。接下来我们首先看一下三者分别是如何创建的。

二.activity是如何创建的

首先看到入口类activitythreadperformlaunchactivity方法:

有句特别关键的代码,即

所以activityinstrumentation类的newactivity方法创建的,追踪过去,源码如下

追踪源码,可知getfactory方法返回一个appcomponentfactory对象,然后调用appcomponentfactoryinstantiateactivity方法,继续追踪

到这里就结束了,我们可以发现activity是通过反射创建的。

三.phonewindow的创建

我们还是回到activitythreadperformlaunchactivity方法,在刚刚展示的那一段的下面有如下部分代码

activity.attach这个方法中,传入了一个window对象,追踪这个attach方法,里面有一句关键代码

此时就创建了phonewindow。所以我们可以知道,在activity创建完之后,会为当前的activity创建一个phonewindow对象。

四.decorview的创建

decorview的创建就不是performlaunchactivity方法里面了,这次我们从activitysetcontentview的源码开始分析。下面的activitysetcontentview方法的内容。

我们发现,activitysetcontentview实际是调用了phonewindowsetcontentview方法,跟踪源码。我们会首先进入window抽象类,然后我们找其子类phonewindow,在里面找到setcontentview方法

mcontentparentnull时,会调用installdecor方法,追踪进入

它调用了generatedecor方法,追踪进入

会发现generatedecor方法会创建一个decorview对象,并且作为返回值返回。再追踪decorview

会发现decorview其实是一个framelayout 。到这就介绍完decorview是如何创建的了

五.布局加载流程

我们回到phonewindowinstalldecor方法,再刚刚看的部分的下面,有(2692行)

追踪进入

分析源码和源码注释可以看出generatelayout方法的核心功能是完成decorview的布局加载,而且根据不同的主题样式会加载不同的系统默认布局。那么比如有framelayout布局,它如何加载到decorview中呢?
generatelayout方法中,有这么一句

追踪进入

关键在这里

可以看到layoutresource作为参数,通过inflate方法进行解析加载。然后作为参数,传入addview方法,将布局挂载到上面。至此完成了decorview的默认布局加载。如果是我们自己编写的布局是如何加载呢?再回到generatelayout

,在此之后,有这么一句

decorview执行onresourcesloaded方法加载完默认布局后,会查找id为id_android_content的控件(默认布局中的framelayout控件)并作为generatelayout方法的返回值,我们回到setcontentview方法中,可观察到以下代码:

所以,我们自己编写的布局是被加载到decorview中id为id_android_content的控件上

六.总结

activity创建后会创建出一个phonewindow对象,当在activity中调用setcontentview时,实际上是调用了phonewindowsetcontentview方法,此时phonewindow会创建根布局decorview,并根据主题样式,为decorview加载对应的默认系统布局,在默认的系统布局中包含了一个id为id_android_content的控件,而我们自己编写的布局就是加载到这个控件中的。

以上就是详解android布局加载流程源码的详细内容,更多关于android布局加载流程源码分析的资料请关注其它相关文章!