天天看点

从源码的角度说说Activity的setContentView的原理(二)

1.在PhoneWindow的setContentView里我们看到了一个mLayoutInflater对象,我们还没清楚它从哪来?

2.mLayoutInflater对象后来所调用的那些方法有没有被重载?

3.mFactory,mFactory2, mPrivateFactory这三个对象是否不为空?如果系统默认给它设置了值,那么后来生成的View是不是就是通过它们来设置的呢?

好,接下来就让我们一起把这些问题解开:

1.

我们先来看看mLayoutInflater从哪来,我们推测它极有可能和我们一样是使用这样的方式得来的:

但,这仅仅是推测,我们要看到实际的代码:

通过查看源码我们可以得知,在PhoneWindow的构造方法里是LayoutInflater.from(context);的方式对mLayoutInflater对象进行了初始化,看来,它也是和我们一样使用了同一个系统提供的LayoutInflater对象,那么,系统提供的这个LayoutInflater对象是在哪被构造和添加进去的呢?这我们就需要去Context.getSystemService方法里一探究竟了:

我们知道getSystemService其实调用的就是ContextImpl的方法,ContextImpl是Context的具体实现类,我们进入ContextImpl的getSystemService中一探究竟:

好,看来所有的服务都是通过SYSTEM_SERVICE_MAP取出来的,那么我们看看这些服务什么时候被添加进去的,在ContextImpl这个类中我们看到有个静态方法:

看来所有的服务都是通过它加进去的,那什么时候加进去的呢,我们在这个类当中可以看到一段很长的静态代码块,在代码块中发现了它的身影:

噢,原来所有的工作都是它在干啊!到这里,我们第一个问题就清楚了。

2.mLayoutInflater对象后来所调用的那些方法有没有被重载?其实这个问题我们直接进PhoneLayoutInflater中就可以知道答案:

噢,原来我们在上一篇文章当中分析的onCreateView方法是没有被调用的,那看来父类中的这个方法的功能是不满足的,那我们分析分析被复写的这个方法:

我们可以看到这个方法内部在遍历一个字符串数组,这个字符串数组被定义在类里:

在上一篇文章当中,我请大家在onCreateView中注意调用createView方法的第二个参数是"android.view.",这里被重写,看来是不满足了,子类实现了更为强大的功能,支持了更多的包进行加载,它这个过程一直在尝试去创建View,直到成功。好,我们第二个问题也解决完了。

3.mFactory,mFactory2, mPrivateFactory这三个对象是否不为空?看来这个问题我们就都知道了,PhoneLayoutInflater在构造的时候调用的是:

后来也没有对它进行什么设置,所以看来它们都是空,这里这3个对象是开放给我们使用的,我们可以在View被加载的时候动态的修改它们的效果,这是个很强大的功能,比如动态修改皮肤什么的,希望你们可以手动去实现一下,,谢谢。