启动应用前准备
启动电源后,先做一系列处理,主要是init进程的启动。init进程作为空户空间的第一进程,需要做很多重要工作,主要是创建zygote孵化器服务等。 Android系统中,Dalvik虚拟机、应用程序进程、系统各种关键服务进程都是由Zygote进程通过folk复制的形式来创建的,所以称之为孵化器。
Zygote会fork孵化出一个System Server,它会启动所有系统核心服务,比如ActivityManagerService、PackageManagerService等。最后Zygote还会启动第一个App,也就是Laucher应用。
手机的桌面就是这个Laucher了,它会通过PackageManager获取手机里面已经安装的各种软件,然后将图标显示出来。然后我们就可以通过点击这些图标去启动某个应用。
启动应用流程
图片来自网络
- 点击桌面App图标,Launcher进程采用Binder IPC向ActivityManger发起startActivity请求;(AMS在system_server进程中,这个进程是zygote孵化的第一个重要系统进程)
- AMS接收到请求后,向zygote进程发送创建进程的请求;
- Zygote进程fork出新的子进程,即App进程;
- App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
- system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
- App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
- 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。
调用链详细版流程:
- 用户点击桌面图标的时候,会通过BinderIPC调用System Server中ActivityManagerService的startAcitivityLocked方法。
(Laucher和System Server都是Zygote孵化出来的不同进程,进程间无法直接通讯,所以用Binder进行IPC) - AMS再经过一系列处理(解析Intent里的信息,封装信息,判断是否有目标页面,是否有权限可以打开灯等)最后会调用Process.start方法。
- 然后Process会再调用Zygote,让其fork复制孵化出来一个新的目标应用进程。
- Zygote在孵化出应用进程后,会再实例化ActivityThread对象并调用其main方法,同时返回新进程的pid保存下来。
流程图继续下接应用启动后的初始化:
其中ActivityThread的main方法是程序启动入口
入口代码中会新建一个线程,然后prepareMainThread将其处理为安卓中的UI主线程,主要是给这个线程绑定一个MainLooper,这个就是Handle机制的那套了,最后调用Looper.loop方法开始轮询启动主线程消息队列。
main方法中还会再做一个Application绑定处理,将进程和指定的Application绑定起来,绑定完成后,就会在App进程里保存一个Application对象了。
绑定好Application后,就可以直接startActivity启动目标进程页面了。
这里是由AMS调用realStartActivity方法开始
ActivityThread中会发送一个LAUNCHER_ACTIVITY消息到队列中,队列消息执行,然后ActivityThread将事件交于Instrumentation具体实施,比如newActivity然后调用onCreate方法,Instrumentation 最终调用目标页面的onCreate回调方法,完成~
启动流程理解
可以把手机看做一个公司。
- 公司开始的时候,有个发起人(init进程)
- 他会起好公司名,办手续等等各种基本东西整好~
- 然后定下一个模式(Zygote进程),领导说我准备按照这个模式去挨个组建公司具体团队(Zygote用于Fork复制孵化进程)
- 公司初始,会先打造一个核心管理团队(System Server)负责统筹以后所有的业务部(App进程),核心团队包括财务啊、战略啊、CEO啊啥的,最重要的是CEO(ActivityServiceManager)
- 最后公司还要再整个办公地点作为门面(Laucher进程)方便CEO进行安排任务
准备好了,下面是具体做事了(打开应用某个页面等)
- CEO在办公室说我想做个啥啥啥事儿(从Laucher打开一个App)~
- 先要判断下我们有没有这个业务部门(判断应用是否存在,还会判断其他东西,这里略过)
- 如果不存在的话先创建一个,用上头定好的团队模式组建新业务部(Zygote孵化新App进程)
- 新业务部建立好后,业务部内部自己找个老大(ActivityThread),
- 然后自己一通整合下(ActivityThread.main方法,初始化UI线程等操作),
- 完了再去CEO那报备下,说我们组好啦,现在我们这个团队就是xxx业务部了(向AMS调用attachApplication)
最后就可以执行CEO下发的任务了(AMS打开某个App页面)
- 然后业务部老大收到消息(App的ActivityThread接收到打开页面消息请求)
- 业务部老大再命令干活的小弟去实施~(ActivityThread让Instrumentation处理页面相关命令)
希望最后的例子能帮你更好的理解~