![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=1739499964-G9LHgcV4vaEfKpGkhyd469k2xlLByrE5-0-a79279550ac55d413de306f5d385ef7b)
图5-2 Application Context的创建过程的时序图
ActivityThread 类作为应用程序进程的主线程管理类,它会调用它的内部类ApplicationThread的scheduleLaunchActivity方法来启动Activity,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer138.jpg?sign=1739499964-3ZssDlyZFHOi3F5nSpPmdmA5OGOrSX32-0-2a0cb9d9b7ed5bd2738ad72b37ec344e)
在ApplicationThread的scheduleLaunchActivity方法中向H类发送LAUNCH_ACTIVITY类型的消息,目的是将启动Activity的逻辑放在主线程的消息队列中,这样启动Activity的逻辑会在主线程中执行。我们接着查看H类的handleMessage方法对LAUNCH_ACTIVITY类型的消息的处理:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer139.jpg?sign=1739499964-5Pj9kDVhX3bJKIyg6zciwOABqlbONcIt-0-e586d2dc5815eb2e133ffe4a7da670d3)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer140.jpg?sign=1739499964-EhtUYVJ6tdMAaDGdm75MmgpudRj4wsMV-0-a31953649553bf8dbfc53ace611593c1)
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=1739499964-nGgcqShSU6vCVxizDsuWJK84kr69NWv6-0-647cc0e906a52642f1d4a4dd080ff3d1)
在handleLaunchActivity方法中调用了ActivityThread的performLaunchActivity方法:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer142.jpg?sign=1739499964-Srt7oEPtMbs8wTKjXkXR6AJpExe4ykgF-0-bcc320035e7bbe4fecfaa74c6cc40d6c)
在performLaunchActivity方法中有很多重要的逻辑,这里只保留了和Application Context相关的逻辑,想要了解更多performLaunchActivity方法中的逻辑请查看4.1.3节的内容。ActivityClientRecord的成员变量packageInfo是LoadedApk类型的,我们接着来查看LoadedApk的makeApplication方法,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer143.jpg?sign=1739499964-YoQUtJF1L1bXEkNTT88Ou7G4gkxbrgP4-0-b09b6b2fb3c881b3f244c7e0a0e04fd7)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer144.jpg?sign=1739499964-UL26Sa0wqxq1iZuONsuviNhbL1ECCA1s-0-7b0dc7183db739df4da1ba79ffdfb03a)
在注释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=1739499964-WBmCSbVAtiEcNrAniKIaIY9W3QFmt5xE-0-4187dadc8e4627df4fb1ec114251e43c)
Instrumentation中有两个newApplication重载方法,最终会调用上面这个重载方法。注释1处通过反射来创建Application,并调用了Application的attach方法,将ContextImpl传进去,最后返回该Application,Application的attach方法如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer146.jpg?sign=1739499964-6I8Be0BE8lVuKfl4eilNEwVQWbbSa3R6-0-8e505627601380a8cf53dc62c5a19144)
在attach方法中调用了attachBaseContext方法,它在Application的父类ContextWrapper中实现,代码如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer147.jpg?sign=1739499964-UDCXbRMtkgGbXK0xsiyOLyTImhqtzGr2-0-7df1bb32e6c1726f07f5e4b16a3f0305)
这个base一路传递过来指的是ContextImpl,它是Context的实现类,将ContextImpl赋值给ContextWrapper的Context类型的成员变量mBase,这样在ContextWrapper中就可以使用Context的方法,而Application继承自ContextWrapper,同样可以使用Context的方法。Application的attach方法的作用就是使Application可以使用Context的方法,这样Application才可以用来代表Application Context。
Application Context的创建过程就讲到这里,接下来我们来学习Application Context的获取过程。