1.1 简介
ActivityManagerService简称AMS是Android提供的一个用于管理Activity和其他组件运行状态的系统进程。AMS寄存在systemService中的,在系统启动时会创建一个线程来循环处理客户的请求。同时会向ServiceManger注册很多服务,例如activity,meminfo,cpuinfo等。
1.2 核心类
ActivityStack和ActivityTask, ActivityStack是Activity的记录者和管理者,同时也为AMS管理系统运行情况提供基础,在创建AMS的线程时,会创建一个ActivityStack;ActivityTask是Android应用程序中的一大利器.
1.3 管理当前系统中Activity状态-------ActivityStack
在查看AMS的代码时,会遇到一个mMainStack的变量,它是ActivityStack类型的变量,在AMS启动时就创建了
m.mMainStack = new ActivityStack(m, context, true,thr.mLooper);
从名称可以看出该类是管理Activity的,究竟是不是这样子,看一下我们的分析,在ActivityStack.java中提取了如下内容
1)ActivityState
描述了一个Activity可能经历的所有状态。定义如下:
enum ActivityState {INITIALIZING,RESUMED,PAUSING,PAUSED,STOPPING,STOPPED,FINISHING,DESTROYING,DESTROYED}
2)Arraylist
除了状态管理外,ActivityStack内还有很多ArrayList成员列表,共同点是列表元素是ActivityRecord-----记录每个Activity的运行时信息
mHistory 所有Activity信息都在这里记录除非被destroyed
mLRUActivities 正在运行的Activity的列表集合,以最近使用情况来排序的
mStoppingActivities 列表中的Activity已经可以被stop
1.4 小结
AMS是通过ActivityStack来记录、管理系统中的Activity的状态,并提供查询功能。
1.主要功能是管理记录查询
2.AMS是系统进程的一部分,运行在一个独立的线程中
2. StartActivity流程
StartActivity(Intent)用于启动一个目标Activity,具体的Activity是通过Intent匹配到的,可以是调用者所在的package,也可以是其他进程中的组件
1)如果匹配到的目标对象,其所属程序包中已经有其他元素在运行,即该进程已经启动,则AMS会通知该进程启动目标Activity
2)如果当前Activity所属程序没有进程在运行,AMS就会先启动它的一个实例,然后让其运行目标Activity
大致讲一下startActivity所经历的函数调用流程,从调用方Activity1开始:Activity1---->startActivity@ContextImpl.java--->execStartActivity@Instrumentation.java--->
startActivity@ActivityManagerService.java,调用者的最终还是在AMS中实现。
2.1)调用到startActivityAsUser@ActivityManagerService.java,主要是做了权限的检查,检查调用者是否属于被隔离的对象,同时检查调用者是否有权限执行这一操作
2.2) startActivityMayWait@ActivityStack.java 检查目标Activity是否是显式Activity,同时判断目标Acitivity是不是重量级的,如果当前系统中已经存在重量级进程,就要给Intent重新赋值
2.3)startActivityLocked@ActivityStack.java 源码中带有locked的函数,用于提醒我们保证这些函数的线程安全,该流程主要是判断调用者本身的线程是存在的,同时还会检查调用者是否有权限来启动指定的Activity.
2.4)startActivityUnchecnedLocked@ActivityStack.java 首先处理Intent中的标志位:FLAG_ACTIVITY_NO_USER_ACTION。这个标志表示并不是用户主动启动的Activity,例如来电显示闹钟等。同时会校验START_FLAG_ONLY_IF_NEEDED,只在需要的情况下才启动目标,若被启动和启动的是同一个对象,则没有必要启动了;判断是否需要启动新的Task,这个流程是根据Activity的LaunchFlag决定的。
2.5)startAcitivityLocked@ActivityStack.java,目标Activity不是新的task,则需要找出老的Task来启动,如果找到后该Activity还是不可见的,则将其加到mHistory,并在WMS中做好注册,但不启动。接着将创建的ActivityRecord放到栈的最顶端,这样才能与用户交互。如果目标Activity不是AMS中的第一个,则执行切换动画,接着讲Activity的appToken添加到WMS中,这样该Activity在WMS中就有档可查了。
2.6) resumeTopActivityLocked 判断当前运行的Activity是否是要运行的,如果是就没有必要启动了。如果目标Activity正在stop状态,则需要从mStoppingActivities中移除。
1)如果mPausingActivity不为空,说名当前正在pause前一个activity,我们要等到执行结束才能继续执行,所以会返回false
2)如果mResumingActivity不为空,说明前一个Activity正在执行,需要先pause才能继续操作
3)在启动新的Activity之前,需要通知WMS前一个现实的Activity即将被隐藏,接下来需要启动Activity了,分为两种情况1)目标Activity所在进程已经有实例运行,然后
WMS该Activity已经具备了显示的条件,需要更新一些全局变量,如mResumedActivity,并刷新相关计数,如updateCpuStats,addRecentTaskLocked等,通知等待
的进程,告知目标线程resume指定的Activity。2)目标Activity所在进程还没启动,会通知zygote来启动一个新进程,通过Process.start来启动引用进程,启动后会
通知AMS,AMS预留了一段时间来等待着一回调,假如被启动的进程没有在指定的时间内完成attachAplication回调,AMS就会认为发生了异常。如果新启动的进程
在规定的时间内正常调用attachApplication,那么AMS就会判断当前是不是有Activity在等待这个进程的启动,如果是的话就调用realStartActivityLocked继续之前任务
接下来就会走Activity的生命周期onCreate->onStart->onResume等,并且WMS与SurfaceFlinger的配合下,目标的Activity描述的UI界面会呈现在屋里屏幕上。
3. 完成同一任务的集合----ActivityTask
Android系统中应用程序的一大特色,它们不仅可以装载众多系统组件,同时可以把这些组件跨进程地组成ActivityTask,从而最大限度的复用资源。