![Android进阶解密](https://wfqqreader-1252317822.image.myqcloud.com/cover/331/31186331/b_31186331.jpg)
5.2 Application Context的创建过程
我们通过调用getApplicationContext来获取应用程序全局的Application Context,那么Application Context是如何创建的呢?在一个应用程序启动完成后,应用程序就会有一个全局的Application Context,那么我们就从应用程序启动过程开始着手。Application Context的创建过程的时序图如图5-2所示。
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer137.jpg?sign=1738885387-9ctQorc31ZpPVoA0emUDNZeOdFh5YLt7-0-5b8890a78de0ca3de38d132fc2df57e9)
图5-2 Application Context的创建过程的时序图
ActivityThread 类作为应用程序进程的主线程管理类,它会调用它的内部类ApplicationThread的scheduleLaunchActivity方法来启动Activity,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer138.jpg?sign=1738885387-pYbrE3eks0M43h6gmmSCSmfRGnadmigj-0-83d32e07486f7d78ae8bd9cc74957261)
在ApplicationThread的scheduleLaunchActivity方法中向H类发送LAUNCH_ACTIVITY类型的消息,目的是将启动Activity的逻辑放在主线程的消息队列中,这样启动Activity的逻辑会在主线程中执行。我们接着查看H类的handleMessage方法对LAUNCH_ACTIVITY类型的消息的处理:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer139.jpg?sign=1738885387-GJ54Xt3OC0OhvGesOulpcG8yQyRtFiW9-0-6a5d3189dbd1e1f7280dc2db3976da20)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer140.jpg?sign=1738885387-1bYUiXLf96SbTfOzCBteLWPdRkFsEYO3-0-f63b66208959126f4595405a91f1d8f1)
H继承自Handler,是ActivityThread的内部类。在注释1处通过getPackageInfoNoCheck方法获得LoadedApk 类型的对象,并将该对象赋值给ActivityClientRecord的成员变量packageInfo,其中LoadedApk用来描述已加载的APK文件。在注释2处调用了ActivityThread的handleLaunchActivity方法,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer141.jpg?sign=1738885387-SQucemcXJQV16JneT6MWva87BmSbcETc-0-a28c98f599a84bcc24e8916bec710633)
在handleLaunchActivity方法中调用了ActivityThread的performLaunchActivity方法:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer142.jpg?sign=1738885387-2F5JqYT621NNsGbM8Fi5ka6DeqkBEUwh-0-0cb1efcca0520826b3e121fc81e059c7)
在performLaunchActivity方法中有很多重要的逻辑,这里只保留了和Application Context相关的逻辑,想要了解更多performLaunchActivity方法中的逻辑请查看4.1.3节的内容。ActivityClientRecord的成员变量packageInfo是LoadedApk类型的,我们接着来查看LoadedApk的makeApplication方法,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer143.jpg?sign=1738885387-IzGFnaF4iebgFMuGJmNTjSnDBtL43haK-0-9a136dce6eac98b8322650708c2a3438)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer144.jpg?sign=1738885387-lNMPQQXVt247QdCfoZAMHr1JmF6anPoq-0-31104911f5f72c866a27a78c78b61e53)
在注释1处如果mApplication不为null则返回mApplication,这里假设是第一次启动应用程序,因此mApplication为null。在注释2处通过ContextImpl的createAppContext方法来创建ContextImpl。注释3处的代码用来创建Application,在Instrumentation的newApplication方法中传入了ClassLoader类型的对象以及注释2处创建的ContextImpl。在注释4处将Application赋值给ContextImpl的Context类型的成员变量mOuterContext,这样ContextImpl中也包含了Application的引用。在注释5处将Application赋值给LoadedApk的成员变量mApplication,这个mApplication是Application 类型的对象,它用来代表Application Context,在Application Context的获取过程中我们会再次提到mApplication。下面来查看注释3处的Application是如何创建的,Instrumentation的newApplication方法如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer145.jpg?sign=1738885387-vmwOJtenBmWOiNFdhfiAyx3jQcuD3irP-0-1b1689b21c195b2714388da2ed27a531)
Instrumentation中有两个newApplication重载方法,最终会调用上面这个重载方法。注释1处通过反射来创建Application,并调用了Application的attach方法,将ContextImpl传进去,最后返回该Application,Application的attach方法如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer146.jpg?sign=1738885387-53ZOxcowQhwDt6Uj6Mbq6Z8UMr2ADqWJ-0-2587ecc06f64d5ebe01ef77a10ed48c7)
在attach方法中调用了attachBaseContext方法,它在Application的父类ContextWrapper中实现,代码如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer147.jpg?sign=1738885387-HmjvVCLatxCEhg6hu9e7iftmIqh6dLQP-0-6911837097772dc48f281007592c160e)
这个base一路传递过来指的是ContextImpl,它是Context的实现类,将ContextImpl赋值给ContextWrapper的Context类型的成员变量mBase,这样在ContextWrapper中就可以使用Context的方法,而Application继承自ContextWrapper,同样可以使用Context的方法。Application的attach方法的作用就是使Application可以使用Context的方法,这样Application才可以用来代表Application Context。
Application Context的创建过程就讲到这里,接下来我们来学习Application Context的获取过程。