一个APP从启动到主页面经历了哪些过程?
流程图
启动流程:
点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
system_server进程接收到请求后,向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()等方法。
到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。
理论基础
1.zygote
类似于Linux系统,在Linux中所有进程都是由init进程直接或间接fork出来的。这里的zygote相当于init进程。
每一个App都是:
- 一个单独的dalvik虚拟机
- 一个单独的进程
Android内核加载完后会启动一个zygote进程,之后开启新进程的方式都是通过zygote实现的。
2.system_server
system_server进程和zygote进程是Framework里非常重要的两大进程。
因为系统里面的重要服务都是在这个进程里面开启的,比如:
AMS(ActivityManagerService)、PMS(PackageManagerService)、WMS(WindowManagerService)
3.ActivityManagerService
ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。
ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService。
什么是Android系统里面的服务器和客户端的概念?
其实服务器客户端的概念不仅仅存在于Web开发中,在Android的框架设计中,使用的也是这一种模式。服务器端指的就是所有App共用的系统服务,比如我们这里提到的ActivityManagerService,和前面提到的PackageManagerService、WindowManagerService等等,这些基础的系统服务是被所有的App公用的,当某个App想实现某个操作的时候,要告诉这些系统服务,比如你想打开一个App,那么我们知道了包名和MainActivity类名之后就可以打开
类似于浏览器把网页地址发送给服务器,服务器把资源文件返回给客户端。
应用启动时,哪些进行的是Binder通信,哪些进行的是Socket通信?
App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信,以及App与zygote之间是通过Socket进行IPC通信的。
启动一个应用和启动一个Activity有什么区别?
在Android系统中,任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。
4.Launcher
Launcher本质上也是一个应用程序,和App一样,也是继承自Activity.
packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
1 | public final class Launcher extends Activity |
当我们点击图标的时候,是怎么开启的应用呢?
Launcher通过捕捉图标点击事件,然后startActivity()发送对应的Intent请求。
5.Instrumentation大管家
每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。
这个类主要是完成对Application和Activity初始化和生命周期的工具类。
6. ActivityThread外交官
ActivityThread,依赖于UI线程。App和AMS是通过Binder传递信息的,那么ActivityThread就是专门与AMS的外交工作的。
7.ApplicationThread
客户端 -> 服务端
服务端 -> 客户端
启动流程
1. 创建进程
- App发起进程:从桌面启动应用,发起方位Launcher所在进程;当从App内启动进程,发起方为App所在进程。发起进程先通过binder发送消息给system_server进程。
- system_server进程:调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求。
- zygote进程:在执行ZygoteInit.main()后,进入runSelectLoop()循环体内,当有客户端连接时会执行ZygoteConnection.runOnce()方法,再经过层层调用fork出新的应用进程。
- 新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法。
2. 绑定Application
这一步的目的是为了将进程和指定的Application绑定起来。
- ATP: ApplicationThreadProxy
- AT: ApplicationThread
- AMP: ActivityManagerProxy
- AMS: ActivityManagerService
- AMN: ActivityManagerNative
- ActivityThread调用startProcessLocked方法,利用Zygote fork()方法,
- AMS调用start
3. 显示Activity界面
- system_server进程的AMS调用realStartActivityLocked
- 然后ATP调用scheduleLaunchActivity,会调用Application线程对象的scheduleLauchActivity()发送一个LAUNCH_ACTIVITY消息到消息队列中。
- 通过handleLaunchActivity的performLaunchActivity()来回调Activity的onCreate()和onStart()方法。
- 通过handleResumeActivity()方法,回调Activity的onResume()方法,最终显示Activity界面。