AMS重要的数据结构
基于Android U
ActivityRecord
ActivityRecord内部记录了Activity的所有信息。因此它用来描述一个Activity,它是在启动Activity时被创建的,具体是在ActivityStarter的startActivity方法中被创建的。ActivityRecord的部分重要成员变量如下所示:
名称 | 类型 | 说明 |
---|---|---|
service | ActivityManagerService | AMS的引用 |
info | ActivityInfo | 开发者在AndroidManifest中提供的Activity信息 |
launchedFromPackage | String | 启动Activity的包名 |
taskAffinity | String | Activity希望归属的栈 |
task | Task | ActivityRecord所在的Task |
app | WindowProcessController | ActivityRecord所在的应用程序进程 |
mState | State | 当前Activity的状态 |
icon | int | Activity的图标资源标识符 |
theme | int | Activity的主题资源标识符 |
ActivityRecord中含有该ActivityRecord所在的Task,这就将ActivityRecord和Task关联在一起,它们是Activity任务栈模型的重要成员。
TaskFragment
一个基本容器,可容纳 Activity 或其他 TaskFragment,还能够管理Activity生命周期及更新其可见性。
在TaskFragment中定义了一些特殊状态的Activity,如下所示:
1 |
|
Task
Task是一个TaskFragment(继承自TaskFragment),用来描述一个Activity任务栈,其内部也有很多的成员变量,如下所示:
名称 | 类型 | 说明 |
---|---|---|
mTaskId | int | 任务栈的唯一标识符 |
affinity | String | 任务栈的倾向性 |
intent | Intent | 启动这个任务栈的Intent,可能为null |
Task内部存储了任务栈的所有信息,包括任务栈的唯一标识符、任务栈的倾向性、任务栈中的Activity记录等。
ActivityState
在ActivityRecord中通过枚举存储了Activity的所有的状态。
1 |
|
ActivityTaskSupervisor
用来替代ActivityStackSupervisor,是Activity的核心调度类,其中有一些Activity List。
1 |
|
Activity栈管理
有了栈管理,我们可以对应用程序进行操作,应用可以复用自身应用中以及其他应用的Activity,节省了资源。比如我们使用一款社交应用,这个应用的联系人详情界面提供了联系人的邮箱,当我们点击邮箱时会跳到发送邮件的界面。

Launch Mode
用于设定Activity的启动方式,无论是哪种启动方式,所启动的Activity都会位于Activity栈的栈顶,主要有以下四种Launch Mode:
standard:默认模式,每次启动Activity都会创建一个新的Activity实例。
singleTop:如果要启动的Activity已经在栈顶,则不会重新创建Activity,同时该Activity的onNewIntent()方法会被调用。如果要启动的Activity不在栈顶,则会重新创建该Activity的实例。
singleTask:如果要启动的Activity已经存在于它想要归属的栈中,那么将栈中位于该Activity上的所有Activity出栈,同时该Activity的onNewIntent()方法会被调用。如果要启动的Activity不存在于它想要归属的栈中,如果该栈存在,则创建该Activity的实例,如果该栈不存在,则首先要创建一个新栈,然后创建该Activity实例并压入到新栈中。
singleInstance:启动Activity时,首先要创建一个新栈,然后创建该Activity实例并压入新栈中,新栈中只会存在这一个Activity实例。
Intent的FLAG
在Intent中定义了很多FLAG,其中有几个FLAG也可以设定Activity的启动方式,如果Launch Mode和FLAG设定的Activity的启动方式有冲突,则以FLAG设定的为准。
- FLAG_ACTIVITY_SINGLE_TOP:和Launch Mode中的singleTop效果一样。
- FLAG_ACTIVITY_NEW_TASK:和Launch Mode中的singleTask效果一样。
- FLAG_ACTIVITY_CLEAR_TOP:Launch Mode中没有与此对应的模式,如果要启动的Activity已经存在于栈中,则将所有位于它上面的Activity出栈。singleTask默认具有此标记的效果。
除了上述三个FLAG,还有一个FLAG和栈管理相关。
- FLAG_ACTIVITY_NO_HISTORY:Activity一旦退出,就不会存在于栈中。同样地,也可以在AndroidManifest.xml中设置android:noHistory。
- FLAG_ACTIVITY_MULTIPLE_TASK:需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,系统会启动一个新的栈来容纳新启动的Activity。
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:Activity不会被放入到“最近启动的Activity”列表中。
- FLAG_ACTIVITY_BROUGHT_TO_FRONT:这个标志位通常不是由应用程序中的代码设置的,而是Launch Mode为singleTask时,由系统加上的。
- FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY:这个标志位通常不是由应用程序中的代码设置的,而是从历史记录中启动的(长按Home键调出)。
- FLAG_ACTIVITY_CLEAR_TASK:需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,用于清除与启动的Activity相关栈的所有其他Activity。
taskAffinity
我们可以在AndroidManifest.xml中设置android:taskAffinity,用来指定Activity希望归属的栈,在默认情况下,同一个应用程序的所有的Activity都有着相同的taskAffinity。taskAffinity在下面两种情况时会产生效果。
(1)taskAffinity与FLAG_ACTIVITY_NEW_TASK或者singleTask配合。如果新启动Activity的taskAffinity和栈的taskAffinity相同则加入到该栈中;如果不同,就会创建新栈。
(2)taskAffinity与allowTaskReparenting配合。如果allowTaskReparenting为true,说明Activity具有转移的能力。举例:当社交应用启动了发送邮件的Activity,此时发送邮件的Activity是和社交应用处于同一个栈中的,并且这个栈位于前台。如果发送邮件的Activity的allowTaskReparenting设置为true,此后E-mail应用所在的栈位于前台时,发送邮件的Activity就会由社交应用的栈转移到与它更亲近的邮件应用(taskAffinity相同)所在的栈中。
