APP启动流程(startActivity)原理

821 阅读4分钟

startActivity原理流程

    Android系统中,使用startActivity来启动一个新的activity有两种情况,一种是用户点击桌面APP图标,打开一个APP时候,会调用startActivity来启动APP。另一种就是APP中打开一个新的activity。

APP启动流程-1.png

上图是startActivity方法调用后,系统源码主要做了哪些事情。

总结来讲:

  1. 无论是通过桌面APP(LaunchActivity)还是APP内想要打开一个新的activity页面,最终调用的都是activity中的startActivity方法。
  2. 因为启动一个Activty步骤很繁琐,都是由系统服务AMS统一管理activity的创建和启动,所以这里通过AIDL调用AMS方法来startActivity。
  3. 其中中间层Instrumentation类主要是为了单元测试而中间代理了一层。
  4. 回到AMS中,AMS里会先判断当前想要启动的Activty所在的进程是否存在,如果不存在,说明还没启动,这里会决定是否启动其进程,以便后续处理。
  5. 根据Activity设置的启动模式flag,来确定是否使用缓存的activity还是新建一个activity,以及对该activity栈进行处理,是新建一个,还是直接放到栈中呢?还是需要清理一下栈中其他activity呢?
  6. 通过上述一系列判断处理,会生成一个对象ActivityRecord对象,该对象主要记录Activty相关信息。
  7. 根据第4步判断结果,如果目标activity进程不存在,那么会走到zogyte进程中,由zogyte forck出一个进程来启动目标APP,这里接下来会走到目标APP进程的ActivityThread的main方法中,进行后续APP启动流程。如果目标activity进程存在,那么会找到其对应的ApplicationThread代理,通过AIDL方式,调用其对应方法,发送msg消息到ActivityThread中来启动activity。

    进入到activityThread进程中后,接下来流程参考APP启动流程。

APP启动流程

    对于一个APP进程被fork出来后,会调用执行ActivityThread类中的main方法,该方法会实例化ActivityThread对象,调用其attach方法来开始APP启动流程,同时会开启一个looper死循环。

    looper死循环在这里的作用:

  1. 保证进程可以一直运行。防止程序执行结束了,进程也结束了。
  2. 用于接收msg消息传给ActivityThread中的handler进行处理。ActivityThread为APP主线程。
  • 为什么looper不会造成主线程ANR呢?
  1. 因为一个程序的运行,如果逻辑执行结束了,那么程序也就结束了,这里使用looper死循环,保证了APP进程一直存活着,而不会结束。
  2. 第二点就和ANR的本质以及looper原理有关了,下篇文章会分析下。

    下图主要是APP启动流程图。

APP启动流程-2.png

总结下:

  1. 调用AMS中的方法开始流程
  2. 通过传入的ApplicationThread代理,调用其方法进行Application对象的创建,在APP进程中会发送创建Application的消息到looper队列中。
  3. 保存当前进程到ProcessRecord中
  4. AMS通过ApplicationThread代理发送消息给looper,告知其创建Activity
  5. 如果存在需要启动的Service,AMS通过aApplicationThread代理发送消息给looper,告知其创建Service。
  6. 如果存在静态广播,AMS会进行广播的处理和分发。

在APP进程中

  1. 收到创建APPlication的消息-> 通过LoadAPK来统一创建Application对象,且调用其onCreate方法
  2. 收到创建activity的消息 -> 通过LoadAPK来创建Activity,且根据需要调用其生命周期方法
  3. 收到创建service的消息 -> 创建service实例,且调用其onCreate方法
  • 为什么ActivityThread中要使用队列来处理消息呢?
  1. 首先APP进程每个组件有其生命周期概念,周期是线性的,即方法调用是线性的,不能存在同时调用两个生命周期方法,比如同时调用onCreate和onStart方法,因为每个生命周期方法有其特殊含义。所以这里使用队列来做限制,可以保证线性处理。
  2. 生命周期方法的调用处理需要一定时间,但是AMS调用APP进程方法后,并不能等待其完全执行完后才可以继续处理,所以AMS进程只需要通过AIDL方式发送消息后,然后就可以继续做接下来的事情了,不需要等待APP进程方法的执行。