系统的启动过程
一、理论基础
1.系统中的所有经常进程都是由Zygote进程fork出来的。当系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的。所以说,除了第一个zygote进程,其他应用所在的进程都是zygote的子进程。2.SystemServer进程是系统进程,很多系统服务,例如ActivityManagerService、PackageManagerService、WindowManagerService…都是存在该进程被创建后启动
3.ActivityManagerServices(AMS):是一个服务端对象,负责所有的Activity的生命周期,AMS通过Binder与Activity通信,而AMS与Zygote之间是通过Socket通信。ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService。
4.ActivityThread:UI线程/主线程,它的main()方法是APP的真正入口。
5.ApplicationThread:一个实现了IBinder接口的ActivityThread内部类,用于ActivityThread和AMS的所在进程间通信。
6.Instrumentation:可以理解为ActivityThread的一个工具类,在ActivityThread中初始化,一个进程只存在一个Instrumentation对象,在每个Activity初始化时,会通过Activity的Attach方法,将该引用传递给Activity。Activity所有生命周期的方法都有该类来执行。
7.Launcher:实现了点击、长按等回调接口,来接收用户的输入。
二、启动流程
1.创建进程
①先从Launcher的startActivity()方法,通过Binder通信,调用ActivityManagerService的startActivity方法。
②一系列折腾,最后调用startProcessLocked()方法来创建新的进程。
③该方法会通过前面讲到的socket通道传递参数给Zygote进程。Zygote孵化自身。调用ZygoteInit.main()方法来实例化ActivityThread对象并最终返回新进程的pid。
④调用ActivityThread.main()方法,ActivityThread随后依次调用Looper.prepareLoop()和Looper.loop()来开启消息循环。
2.绑定Application
上面创建进程后,执行ActivityThread.main()方法,随后调用attach()方法。
将进程和指定的Application绑定起来。这个是通过上节的ActivityThread对象中调用bindApplication()方法完成的。该方法发送一个BIND_APPLICATION的消息到消息队列中, 最终通过handleBindApplication()方法处理该消息. 然后调用makeApplication()方法来加载App的classes到内存中。
3.显示Activity界面
经过前两个步骤之后, 系统已经拥有了该application的进程。 后面的调用顺序就是普通的从一个已经存在的进程中启动一个新进程的activity了。
实际调用方法是realStartActivity(), 它会调用application线程对象中的scheduleLaunchActivity()发送一个LAUNCH_ACTIVITY消息到消息队列中, 通过 handleLaunchActivity()来处理该消息。在 handleLaunchActivity()通过performLaunchActiivty()方法回调Activity的onCreate()方法和onStart()方法,然后通过handleResumeActivity()方法,回调Activity的onResume()方法,最终显示Activity界面。