1.应用程序启动分类

冷启动

    这种方式应用需要完成完整的启动过程,即创建进程、初始化资源及显示应用界面,相比于另外两种启动模式,应用冷启动耗时最长。

热启动

    这种方式下应用进程已经启动,通常只需将要显示的activity带到前台即可,所以在该模式下应用可以较快速启动。

温启动

    这种方式需要完成部分冷启动过程,比如进程已经创建,但要重新执行activity的onCreate()来创建要显示的activity,这种模式下的启动时间介于以上两种之间。

2.应用程序启动相关角色

zygote进程

    zygote意为“受精卵“。Android是基于Linux系统的,而在Linux中,所有的进程都是由init进程直接或者是间接fork出来的,zygote进程也不例外。Android系统启动过程中,会先启动linux内核,然后加载init.rc文件,启动init进程。然后,init进程通过解析init.rc文件fork生成Zygote进程,该进程也是Android系统的首个Java进程。之后Zygote进程负责孵化System Server进程和所有启动的APP进程。

SystemServer进程

    由Zygote进程fork生成,SystemServer是Zygote孵化的第一个进程。负责启动、管理整个Java Framework,系统里面重要的服务都是在这个进程里面开启的,比如AMS(ActivityManagerService)、PMS(PackageManagerService)、WMS(WindowManagerService)。

ActivityManagerService(AMS)

    AMS是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作。还负责启动或杀死应用程序的进程。所有应用在其生命周期内均需和AMS打交道.

PackageManagerService(PMS)

    PMS 用来管理跟踪所有应用APK,包括安装,卸载,解析,控制权限等。

WindowManagerService(WMS)

  1. 为所有窗口分配Surface。
  2. 管理Surface的显示顺序、尺寸、位置。
  3. 管理窗口动画。
  4. 输入系统相关:WMS是派发系统按键和触摸消息的最佳人选,当接收到一个触摸事件,它需要寻找一个最合适的窗口来处理消息。

App进程

    Zygote进程在App层中孵化出的第一个进程是Launcher进程,即手机的桌面APP。Zygote还会孵化出Browser、Email、Phone等APP进程,每个APP至少运行在一个进程上。所有APP进程都由Zygote进程fork生成。

Android Binder机制

    在Android系统中,一个进程的空间,分为用户空间和内核空间两部分。进程内的用户空间和内核空间可以进行数据交互。进程间的用户空间是隔离开来的,只有内核空间能进行数据交互。
    APP进程与SystemServer进程的交互,就是通过Binder机制进行跨进程通信(IPC),实现进程间的内核数据交互过程。Android专门设计了2个Binder接口,用作交互使用
    IApplicationThread: 作为系统进程请求应用进程的接口。(ApplicationThread)
    IActivityManager: 作为应用进程请求系统进程的接口。(Activitythread)

3.应用程序启动流程总结

  1. 当我们点击Launcher桌面程序的APP图标时,Launcher程序会调用startActivity()函数,通过Binder跨进程通信,发送请求消息给system_server进程。
  2. ActivityManagerService接收到请求后,通过socket通信发送请求给Zygote进程,请求fork出一个子进程(APP进程)
  3. Zygote进程fork出新的子进程,即App进程;
  4. APP进程启动后,会实例化一个ActivityThread,并执行其main函数,同时会创建ApplicationThread、Looper、Handler对象,开启主线程消息循环Looper.loop()。
  5. App进程通过Binder IPC向sytem_server进程发起绑定Application请求
  6. system_server进程在收到请求执行attachApplication方法,进行一系列准备工作后其中包括bindApplication以及通过binder IPC向App进程发送scheduleLaunchActivity请求;
  7. App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
  8. 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。
  9. 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。

4.UI布局和绘制:

    主线程Handler初始化Activity时,会执行创建PhoneWindow、初始化DecorView的操作,并且添加布局到DecorView的ContentView中。ContentView,对应着Activity的setContentView中设置的layout.xml布局文件所在的最外层父布局。基本的View绘制流程如下:

  1. 从rootView开始递归向下绘制控件树
  2. ViewGroup负责通知子View进行绘制,子view负责绘制自己本身
  3. 整个绘制由Measure(),Layout(),Draw()三个过程构成

    PS:之前面试的时候面试官问到一个应用程序开启后最少都有那些线程,我觉得回答可以这样说,启动后至少有三条线程,分别是一条UI线程(主线程)两条Binder线程(ApplicationThread以及Activitythread)
    ActivityThread在Android中它就代表了Android的主线程,但是并不是一个Thread类。
    严格来说,UI主线程不是ActivityThread。ActivityThread类是Android APP进程的初始类,它的main函数是这个APP进程的入口。APP进程中UI事件的执行代码段都是由ActivityThread提供的。也就是说,Main Thread实例是存在的,只是创建它的代码我们不可见。ActivityThread的main函数就是在这个Main Thread里被执行的。