Android 中的 Activity 有几种比较重要的启动模式,Standard\SingleTop\SingleTask\SingleInstance , 每一种启动模式有不同的使用场景, 网上也有许多分析这个的文章, 这里我以 Demo 的模式, 从 Activity 栈的角度来展示不同启动模式下的 Activity 的行为.
Activity 栈是一个先进后出的数据结构, 各位可以关注在每一步操作之后, 栈内容那一栏 , 可以更好地帮助理解不同的启动模式.
Demo 比较简单, 我也放到了 Github 上 , [https://github.com/xiangjiana/emmmmm
](https://github.com/xiangjiana/emmmmm
) , 有兴趣的可以自己跑一下 , 看看结果 , 只需要修改 StandardActivity 里面的跳转 Activity 就可以了.
android:launchMode="standard"
最基本的模式,每次启动都会创建一个新的 Activity
// 1. 启动 Activity
MainActivity
//栈内容
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 2. 启动 StandardActivity
MainActivity -> StandardActivity
//栈内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 3. 启动 StandardActivity
MainActivity -> StandardActivity -> StandardActivity
//栈内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
android:launchMode="singleTop"
如果当前 Activity 已经在栈顶,那么其 onNewIntent 会被调用;否则会重新创建 Activity
// 1. 启动 MainActivity
MainActivity
//栈内容
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 2. 启动 StandardActivity
MainActivity -> StandardActivity
//栈内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 3. 启动 SingleTopActivity
MainActivity -> StandardActivity -> SingleTopActivity
//栈内容
com.example.launchmodetest/.SingleTopActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 4. 启动 StandardActivity
MainActivity -> StandardActivity -> SingleTopActivity -> StandardActivity
//栈内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.SingleTopActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 5. 启动 SingleTopActivity:
MainActivity -> StandardActivity -> SingleTopActivity -> StandardActivity -> SingleTopActivity
//栈内容
com.example.launchmodetest/.SingleTopActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.SingleTopActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
//这里由于第三个 SingleTopActivity 不在栈顶,栈顶是 StandardActivity ,所以启动新的 SingleTopActivity 时会重新创建 SingleTopActivity
// 1. 启动 MainActivity
MainActivity
//栈内容
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 2. 启动 StandardActivity
MainActivity -> StandardActivity
//栈内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 3. 启动 SingleTopActivity
MainActivity -> StandardActivity -> SingleTopActivity
//栈内容
com.example.launchmodetest/.SingleTopActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 4. 启动 SingleTopActivity
MainActivity -> StandardActivity -> SingleTopActivity -> SingleTopActivity
//栈内容
com.example.launchmodetest/.SingleTopActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
//SingleTopActivity 收到 am_new_intent ,而不是创建新的 Activity
android:launchMode="singleTask"
// 1. 启动 MainActivity:
MainActivity
//栈内容:
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 2. 启动 StandardActivity
MainActivity -> StandardActivity
//栈内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 3. 启动 SingleTaskActivity
MainActivity -> StandardActivity -> SingleTaskActivity
//栈内容:
com.example.launchmodetest/.SingleTaskActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 4. 启动 StandardActivity
MainActivity -> StandardActivity -> SingleTaskActivity -> StandardActivity
//栈内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.SingleTaskActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 5. 启动 SingleTaskActivity
MainActivity -> StandardActivity -> SingleTaskActivity -> StandardActivity -> SingleTaskActivity
//栈内容:
com.example.launchmodetest/.SingleTaskActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
//备注:SingleTaskActivity 收到 am_new_intent ,将其上面的 StandardActivity Clear 调
在 Manifest 中设置了 android:taskAffinity=”” 之后,启动 SingleTask 会启动一个新的 Task
// 1. 启动 MainActivity
MainActivity
//栈0内容:
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 2. 启动 StandardActivity
MainActivity -> StandardActivity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 3. 启动 SingleTaskWithAffinity
MainActivity -> StandardActivity -> SingleTaskWithAffinity
//栈1内容:
com.example.launchmodetest/.SingleTaskWithAffinity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 4. 启动 StandardActivity
MainActivity -> StandardActivity -> SingleTaskWithAffinity -> StandardActivity
//栈1内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.SingleTaskWithAffinity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 5. 启动 SingleTaskWithAffinity
MainActivity -> StandardActivity -> SingleTaskWithAffinity -> StandardActivity -> SingleTaskWithAffinity
//栈1内容:
com.example.launchmodetest/.SingleTaskWithAffinity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
android:launchMode="singleInstance"
单示例模式顾名思义,启动时,无论从哪里启动都会给 A 创建一个唯一的任务栈,后续的创建都不会再创建新的 A,除非 A 被销毁了
taskAffinity=com.example.launchmodetest
// 1\. 启动 MainActivity
MainActivity
//栈0内容
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 2\. 启动 StandardActivity
MainActivity -> StandardActivity
//栈0内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 3\. 启动 SingleInstanceActivity
MainActivity -> StandardActivity -> SingleInstanceActivity
//栈1内容(多任务里面没有 Task)
com.example.launchmodetest/.SingleInstanceActivity
//栈0内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 4\. 启动 StandardActivity
MainActivity -> StandardActivity -> SingleInstanceActivity -> StandardActivity
//栈1内容(多任务里面没有 Task)
com.example.launchmodetest/.SingleInstanceActivity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 5\. 启动 SingleInstanceActivity
MainActivity -> StandardActivity -> SingleInstanceActivity -> StandardActivity -> SingleInstanceActivity
//栈1内: (多任务里面没有 Task)
com.example.launchmodetest/.SingleInstanceActivity
//栈0内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 6\. 启动 StandardActivity
MainActivity -> StandardActivity -> SingleInstanceActivity -> StandardActivity -> SingleInstanceActivity -> StandardActivity
//栈1内: (多任务里面没有 Task)
com.example.launchmodetest/.SingleInstanceActivity
//栈0内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 7\. 启动 SingleInstanceActivity
MainActivity -> StandardActivity -> SingleInstanceActivity -> StandardActivity -> SingleInstanceActivity -> StandardActivity -> SingleInstanceActivity
//栈1内容 (多任务里面没有 Task)
com.example.launchmodetest/.SingleInstanceActivity
//栈0内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
在 Manifest 中设置了 android:taskAffinity=”” 之后,启动 SingleInstanceActivity 会出现在多任务中 ,其余的表现与没有设置 Affinity 一致
taskAffinity=null
// 1. 启动 MainActivity
MainActivity
//栈0内容:
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 2. 启动 StandardActivity
MainActivity -> StandardActivity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 3. 启动 SingleInstanceWithAffinityActivity
MainActivity -> StandardActivity -> SingleInstanceWithAffinityActivity
//栈1内容:(多任务里面有 Task)
com.example.launchmodetest/.SingleInstanceWithAffinityActivity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 4. 启动 StandardActivity
MainActivity -> StandardActivity -> SingleInstanceWithAffinityActivity -> StandardActivity
//栈1内容:(多任务里面有 Task)
com.example.launchmodetest/.SingleInstanceWithAffinityActivity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 5. 启动 SingleInstanceWithAffinityActivity
MainActivity -> StandardActivity -> SingleInstanceWithAffinityActivity -> StandardActivity -> SingleInstanceWithAffinityActivity
//栈1内容:(多任务里面有 Task)
com.example.launchmodetest/.SingleInstanceWithAffinityActivity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 6. 启动 StandardActivity
MainActivity -> StandardActivity -> SingleInstanceWithAffinityActivity -> StandardActivity -> SingleInstanceWithAffinityActivity -> StandardActivity
//栈1内容:(多任务里面有 Task)
com.example.launchmodetest/.SingleInstanceWithAffinityActivity
//栈0内容
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
-------------------------------------------------------------------
// 7. 启动 SingleInstanceWithAffinityActivity
MainActivity -> StandardActivity -> SingleInstanceWithAffinityActivity -> StandardActivity -> SingleInstanceWithAffinityActivity -> StandardActivity -> SingleInstanceWithAffinityActivity
//栈1内容:(多任务里面有 Task)
com.example.launchmodetest/.SingleInstanceWithAffinityActivity
//栈0内容:
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.StandardActivity
com.example.launchmodetest/.MainActivity
taskAffinity=null
与 Activity 有着亲和关系的任务。从概念上讲,具有相同亲和关系的 Activity 归属同一Task(从用户的角度来看,则是归属同一“ Application ”)。 Task 的亲和关系由其根 Activity 的亲和关系确定。
亲和关系确定两件事 - Activity 更改到的父项 Task(请参阅 allowTaskReparenting 属性)和通过 FLAG_ACTIVITY_NEW_TASK 标志启动 Activity 时将用来容纳它的 Task。
默认情况下,应用中的所有 Activity 都具有相同的亲和关系。您可以设置该属性来以不同方式组合它们,甚至可以将在不同应用中定义的 Activity 置于同一 Task 内。 要指定 Activity 与任何 Task 均无亲和关系,请将其设置为空字符串。
如果未设置该属性,则 Activity 继承为应用设置的亲和关系(请参阅 元素的 taskAffinity 属性)。 应用默认亲和关系的名称是 元素设置的软件包名称。
下面是一个 dump 的例子,可以看到当前手机的 ActivityRecord、TaskRecord、ActivityStack
(adb shell dumpsys activity containers)
/** Activity type is currently not defined. */
public static final int ACTIVITY_TYPE_UNDEFINED = 0;
/** Standard activity type. Nothing special about the activity... */
public static final int ACTIVITY_TYPE_STANDARD = 1;
/** Home/Launcher activity type. */
public static final int ACTIVITY_TYPE_HOME = 2;
/** Recents/Overview activity type. There is only one activity with this type in the system. */
public static final int ACTIVITY_TYPE_RECENTS = 3;
/** Assistant activity type. */
public static final int ACTIVITY_TYPE_ASSISTANT = 4;