无冥冥之志者,无昭昭之明;无惛惛之事者,无赫赫之功。
 解释:没有专心致志地刻苦学习,就没有融会贯通的智慧;没有埋头执着的工作,就不会取得显著的成就。

问题:从Launcher点击应用图标到应用的MainActivity展示过程中发生了哪些事情?

   这是我在面试的时候经常会被问到的问题,它考察的是对应用启动流程及Activity的启动流程是否了解或熟悉。回答这个问题,我的策略是由大到小,由粗到细。意思就是先讲大的方面,然后从大的方面一一深入细讲。

   应用的启动(这里说的是冷启动)流程涉及到四个进程,所以大的方面是讲四个进程及其作用,然后分别讲这四个进程具体做了什么事情。

四个进程

   Android应用的启动涉及了Launcher进程、ActivityManagerService(AMS)进程、Zygote进程及需要启动的应用进程。

1、Launch应用进程

   Launcher是一个系统应用,因此是一个独立进程,在系统启动之后拉起Launcher进程展示桌面。这个过程中,Launcher会通过PMS获取已安装的应用的信息,然后在桌面给这些应用一一分配展示位置。

2、AMS进程

   AMS进程主要负责管理Android的四大组件,包括四大组件对应进程的启动、四大组件生命周期的调用等等。

3、Zygote进程

   Zygote进程负责创建新的应用进程

4、应用进程

   这个就是需要启动的应用所运行的进程。

详细介绍

Launcher进程

   1、当点击Luncher上的图标时,Launcher获取这个图标对应的应用信息,包括进程id、这个应用的MainActivity信息,并把这些信息保存在一个Intent里面。

   2、接着调用Luncher的startActivitySafety方法。在这里会给Intent加入一个标志:FLAG_ACTIVITY_NEW_TASK。表示接下来启动的这个Activity是需要在新的Activity栈中启动。

   3、接着调用Activity类的startActivity(参数1是Intent,参数2根据是否需要启动动画设置的Bundle),在这个方法里调用startActivityForResult方法(参数是前两个参数,参数3是-1,表示Launcher不需要知道应用启动的结果)。

   4、接着调用Instrumentation的execStartActivity方法,在这个方法中通过AMS的远程代理对象调用AMS的startActivity方法。

AMS进程

   5、AMS进程接收发到Launcher进程发起的启动新应用的请求,调用startActivity方法。在这里会调用多个方法,最终通过对象池的方式创建一个ActivityStarter对象。

   6、接着调用ActivityStarter的execute方法,然后调用startActivityMayWait方法。在这个方法中,收集需要启动的应用的信息,包括进程信息,MainActivity信息,然后调用另一个startActivity方法。

   7、创建一个ProcessRecord和一个ActivityRecord的对象,分别存储进程信息和Activity的信息,再调用另一个startActivity方法,这个新的startActivity方法调用了startActivityUnChecked方法。

   8、startActivityUnchecked方法检查需要启动的Activity的启动模式及检查是否需要重新创建一个Activity栈。同时通知Launcher进入paused状态。处理完一系列的栈操作之后,在ActivityStackSupervisor.java中的startSpecificActivityLocked方法判断应用进程是否启动,没启动就启动一个新进程。

   9、AMS以Socket方式通知Zygote需要启动一个新进程。

Zygote进程

   10、负责fork出一个新的进程,及应用进程

应用进程

   11、进程启动之后,先创建一个Binder线程池,然后反射调用ActivityThread的main方法

   12、在main方法中,首先创建应用程序主线程的Looper及MessageQueue对象,接着调用attach方法,告知AMS应用程序启动成功。然后调用主线程的Looper的loop方法启动消息循环。

   13、在attach方法中。通过AMS的远程代理对象,调用attachApplication把一个ApplicationThread对象传递到AMS。这个ApplicationThread对象是一个Binder对象,供AMS与应用程序联系使用。

AMS进程

   AMS接收到应用程序的启动完成通知,调用attachApplicationLocked方法,这个方法会得到发送通知的进程的pid和callerId。然后查找这个应用进程的ContentProvider,通知应用程序启动这些provider。接着再调用的ApplicationThread对象的bindApplication方法,通知应用程序创建一个Application。然后在通知ActivityStackSupervisor.java的attachApplicationLocked方法继续创建启动Activity。

应用程序进程

   应用程序会先后收到创建Application、Activity对象,并执行它们的生命周期方法。

最后

   上述就是从launcher中点击图片发生的事情,其中activity栈相关操作太繁杂,所以一般也不能很好的讲清楚。



results matching ""

    No results matching ""