Android AMS核心分析

AMS提供的主要功能:

  • 统一调度各个应用程序的Activity。

应用程序须要启动Activity–>报告给AMS,决定是否能够启动–>若是能够,通知应用程序运行指定Activity。数据结构

AMS必须知道各个应用程序运行的Activity。异步

  • 内存管理。

Activity退出时不会当即被杀死,只有在内存紧张时才会自动被杀,这些操做由AMS管理。

  • 进程管理。

AMS向外提供了查询系统正在运行的进程信息的API。

AMS的启动

AMS在SystemServer进程initAndLoop()函数中被启动而且初始化。首先看一下SystemServer的启动流程。

SystemServer的启动

android_ams_system_server_start

SystemServer执行流程

android_ams_system_server_invoke

  • AMS.main()函数,建立AMS实例,而且建立Android运行环境获得一个ActivityThread和一个Context。
  • AMS.setSystemProcess()函数,注册AMS服务到ServiceManager中。而且为system_server进程建立ProcessRecord,将该进程归入管理中。
  • AMS.installSystemProvider()函数,为system_server进程加载SettingsProvider。
  • AMS.systemReady()函数,作系统启动完毕后的工做,呈现HomeActivity。

AMS重要数据结构

AMS定义了几个数据类用于Process、Activity、Task信息。

进程数据类ProcessRecord

用于记录一个进程相关信息

android_ams_process_record

保存Activity信息数据类ActivityRecord

用于保存一个Activity的信息。

在ActivityRecord内部提供Token类实现IApplicationToken.Stub能够实现IPC回调其方法。通常是在WMS内部对其IPC调用。

android_ams_activity_record

任务栈信息数据类TaskRecord

记录Activity所属任务栈信息。

android_ams_task_record

Activity的调度机制

Activity调度过程:

应用进程启动或者中止Activity—>报告给AMS,其内部维护全部应用进程启动或者中止Activity的记录—>AMS更新内部记录,并通知客户端进程操做—>客户端进程接收通知,执行操做

启动Activity的各类方式:

  • 应用程序中调用startActivity()
  • 在Home程序中单击应用程序图标启动Activity
  • 按“back”中止当前Activity启动新Activity
  • 长按“home”显示当前任务列表选择一个启动

ActivityThread类关系

android_ams_activity_thread_class_relation

AMS经过Binder跨进程通知ActivityThread启动、中止指定Activity。

ActivityThread做为Binder服务端实现指定接口由AMS远程调用。

ActivityThread能够看作是进程的Android运行环境。

Activity的launchMode

  • standard:默认启动模式,无论有没有已存在的实例都生成新的实例。
  • singleTop:若是栈顶存在对应的实例则重复利用不生产新的实例,不存在则新建实例。
  • singleTask:若是栈内存在对于的实例则使此Activity实例之上的其余Activity实例都出栈,使此Activity实例成为栈顶对象显示。
  • singleInstance:启用一个新栈放入新建Activity实例,而且该栈内只容许存在这一个Activity实例。

Intent中涉及到的Activity启动方式常量:

  • FLAG_ACTIVITY_NEW_TASK:将目标Activity放置到新的task中。
  • FLAG_ACTIVITY_CLEAR_TASK:启动一个Activity时先清除和其有关联的task,并新建Activity实例将其放入新的task中。必须和上面变量一块儿使用
  • FLAG_ACTIVITY_CLEAR_TOP:启动一个不处于栈顶的Activity时,清除排在它前面的Activity使其显示出来。

AMS启动Activity流程

启动过程

android_ams_start_activity_01

整个调用步骤过程以下:

1.首先IPC调用AMS方法传入参数启动指定Activity

2.在AMS中首先查询PKMS获取该ActivityInfo,新建ActivityRecord和根据lunchMod建立TaskRecord两个重要变量,而且将ActivityRecord添加到task栈顶做为准备启动的Activity。

3.在正式启动Activity以前首先检查其进程是否启动,为启动时通知AMS启动对应进程。

下图就是AMS建立Activity对应进程及启动Activity的过程:

android_ams_start_activity_02

整个调用步骤过程以下:

1.首先就是zygote进程fork新进程,指定新进程执行须要启动的ActivityThread类。

2.在ActivityThread的main()方法中:

  • 首先新建ActivityThread对象。
  • 接着回调AMS接口通知其应用进程已启动成功。
  • 最后开启主线程消息循环,处理消息。

3.其中上步骤第二点在与AMS交互中IPC调用AMS的attachApplication()函数中:

  • 首先根据pid查找对应的ProcessRecord
  • 设置该应用退出时的回调接口
  • 修改ProcessRecord一些参数
  • 最后与应用进程交互,开始建立Application对象

4.AMS与应用进程交互时会发出一个异步消息,该消息内部:

  • 配置运行时信息
  • 安装该Application对应的ContentProvider
  • 生成一个Application对象而且回调onCreate()函数

5.AMS与应用进程交互完接着准备启动目标Activity,在ActivityStackSupervisor.attachApplicationLocked()函数中会首先获取须要启动的ActivityRecord并保存到对应的ProcessRecord,接着IPC调用应用进程启动Activity。

6.在应用进程中也是异步消息处理

  • 首先反射实例化目标Activity对象,回调相应onStart()以前的生命周期函数
  • 接着回调onResume()函数而且添加一个Idler消息对象到队列中。该对象内部方法会调用到AMS中的相应方法处理所以次启动而被暂停的Activity的相关声明周期函数处理。

7.同时在AMS中会将task添加到最近任务列表中,而且发送10s定时等待这个Activity处理结果。

8.此时目标Activity已经被成功启动,接着会处理一些Pending组件,这些组件多是在系统启动未成功时发起的一些启动指令。

最终一个Activity启动成功。

Activity启动时序图

android_ams_activity_time_schduce