Android源码分析--应用程序启动

2022-04-18 12:43:08 浏览数 (2)

应用程序的启动,又可称为根Activity的启动。但是在讲应用程序启动之前,我们有必要对应用程序进程(AppProcess)启动有所了解,那是因为启动一个应用程序首先要保证该应用程序的进程已经被启动。AMS在启动应用程序时,会先检查应用程序进程是否存在,如果不存在就需要请求Zygote进程创建并启动应用程序进程。这里我不会贴上大段大段的代码,只是一些总结,并提供了相关源码的链接。

应用程序进程(AppProcess)启动

启动大纲

  1. AMS发送启动应用程序进程请求.
  2. Zygote接收请求并创建应用程序进程.

AMS发送启动应用程序进程请求

1.AMS通过调用startProcessLocked方法向Zygote进程发送请求。

2.Process调用 start方法,使用ZygoteProcess的 start方法。

3.在ZygoteProcess的 start方法中,先后调用了 startViaZygotezygoteSendArgsAndGetResultopenZygoteSocketIfNeeded等方法,最后在 openZygoteSocketIfNeeded方法中调用了ZygoteState的connect方法建立与Zygote进程的连接。

AMS发送启动应用程序进程请求

1.ZygoteServer执行 runSelectLoop方法,一直等待AMS的请求数据到来。

2.当AMS请求到来,与Zygote进程建立连接后,由ZygoteConnection的 processOneCommand方法处理请求的数据。对请求数据进行解析,获取程序进程的启动参数,并通过Zygote的 forkAndSpecialize方法进行应用程序进程的创建。

3.进程创建完成后,交由ZygoteInit的 zygoteInit方法和RuntimeInit的 applicationInit方法分别进行进程和应用的初始化。在 zygoteInit方法中,为应用程序进程创建了Binder线程池,这样进程就可以跨进程进行通信了。而 applicationInit方法通过反射最终会调用ActivityThread的 main方法,从而完成应用程序进程的创建。


应用程序(App)启动

讲完了应用程序进程(AppProcess)启动的相关内容后,接下来我们就来看看应用程序是如何一步一步启动的。

启动大纲

1.Launcher请求AMS。

2.AMS请求ApplicationThread。

3.ActivityThread启动Activity。

启动时序图

Launcher请求AMS

1.当我们点击应用程序的图标时,就会自动调用Launcher的 startActivitySafely方法, 最终会调用Activity的 startActivity方法。

2.在Activity的 startActivity中又调用了 startActivityForResult方法,而 startActivityForResult方法内部又调用了Instrumentation的 execStartActivity方法。

3.在Instrumentation的 execStartActivity方法中又通过ActivityManager的 getService方法获取了IBinder类型的AMS引用 IActivityManager,最后调用了AMS的 startActivity方法。

AMS请求ApplicationThread

1.在AMS的 startActivity方法中,又调用了其本身的 startActivityAsUser方法,进行权限的检查。

2.权限检查完后,调用ActivityStarter的 startActivityMayWait方法,并在该方法中解析处理应用程序需要的参数,并进行相关参数的初始化,最终会调用其 startActivity方法。而在 startActivity方法中又调用了 startActivityUnchecked方法来处理与栈管理相关的逻辑。

3.在处理完栈的关系后,紧接着会调用ActivityStackSupervisor的 resumeFocusedStackTopActivityLocked方法获取需要启动的Activity所在栈的栈顶。

4.当需要启动的Activity的状态不是RESUMED状态,就需要调用ActivityStack的 resumeTopActivityUncheckedLocked方法,而它的内部又调用了 resumeTopActivityInnerLocked方法进行一系列的栈状态的判断,最终又回调了ActivityStackSupervisor的 startSpecificActivityLocked方法。

5.在ActivityStackSupervisor的 startSpecificActivityLocked方法中先是获取了即将启动的Activity所在的应用程序进程(就是在这个地方判断应用所在进程是否存在且已启动,如果没有启动,就需要启动应用程序进程),然后调用 realStartActivityLocked方法。

6.在ActivityStackSupervisor的 realStartActivityLocked方法中,对启动的应用程序进程进行一系列的判断和处理,最终会调用IBinder类型的ApplicationThread引用 IApplicationThread,通过传入 IApplicationThread建立 ClientTransaction,加入执行 LaunchActivityItem任务,最终实现跨进程执行调用ActivityThread的 handleLaunchActivity方法。

ActivityThread启动Activity

1.在ActivityThread调用了它的 handleLaunchActivity方法中,会先调用其 performLaunchActivity方法,之后调用 handleResumeActivity,将Activity的状态置为Resume。

2.在ActivityThread的performLaunchActivity方法中做了很多事情。

(1) 首先,执行了 createBaseContextForActivity方法,创建要启动Activity的上下文;

(2) 其次,调用执行了Instrumentation的 newActivity方法来创建Activity实例;

(3) 接着,调用LoadedApk的 makeApplication方法,创建应用程序的Application;

(4) 之后,调用需要启动的Activity的 attach方法初始化Activity,创建Window对象并与Activity自身进行关联。

(5) 最后,调用执行了Instrumentation的 callActivityOnCreate方法来启动Activity。

3.在Instrumentation执行了 callActivityOnCreate方法中,会调用Activity的 performCreate方法,最终会调用Activity的 onCreate方法,这样应用程序也就启动了。


应用程序启动的进程关系图

应用程序启动的过程中,主要涉及了Launcher进程、SystemServer进程、Zygote进程和应用程序进程这四个进程,它们之间的关系如下。

0 人点赞