standard
默认的,启动Activity的时候无论怎样,都会创建新的实例,并放到当前栈顶
singleTop
如果要启动的Activity和当前Task栈最顶的Activity是同一个,那么不再创建实例,而是调用当前栈顶Activity实例的onNewIntent方法。
singleTask
对应intent的flag “FLAG_ACTIVITY_NEW_TASK” >> 实际测试发现没有作用
taskAffinity的设置使启动singleTask的结果大为不同 。设置了”singleTask”启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的任务存在;如果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。因此,如果我们想要设置了”singleTask”启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。
如果设置了”singleTask”启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。
- 当启动一个singleTask的Activity,并且在处于后台的另外一个Task栈中已存在对应实例,那么会将该Task栈整个的搬到前台
QA
singleTask 会直接创建一个新的Task吗?
视情况而定,如果设置了和当前Task不同的taskAffinity,则会创建一个新的Task。默认情况下,如果从来没有创建该实例,则在当前Task栈顶创建实例。如果已有实例,则调出该实例到栈顶,销毁之上的activity.
使用场景
A sample use case of this mode is any Entry Point Activity for example Email Client’s Inbox page or Social Network’s Timeline. Those Activities are not designed to have more than one instance so singleTask would do a job perfectly. Anyway you have to use this mode wisely since Activities could be destroyed without user’s acknowledgement in this mode like described above.
类似收件箱页面,时间表这种Activity,不让有多个Activity实例。但是singleTask会将目标activity之上的activity实例.
参考
解开Android应用程序组件Activity的”singleTask”之谜
singleInstance
对应intent的flag “FLAG_ACTIVITY_SINGLE_TOP“
和singleTask相似,区别在于singleInstance模式会重新开启一个专享的Task,该Task中只有这一个Activity,当该Activity再次开启其他Activity后,新Activity会被放置到其他的Task中。
注:
This mode is rarely used. Some of the real use case is an Activity for Launcher or the application that you are 100% sure there is only one Activity. Anyway I suggest you not to use this mode unless it is really necessary.
这种模式用的很少,平时慎用。场景有 Launcher Activity.
intent之FLAG_ACTIVITY_CLEAR_TOP vs Manifest中singleTask
intent之FLAG_ACTIVITY_CLEAR_TOP 是intent flag 所特有的,其具有launchMode singleTask的部分功能,即在启动Activity的时候,如果栈中已存在该activity实例,不重新创建实例并将其上的Activity给销毁掉。但二者并不是等同的。
taskAffinity
affinity:密切关系;吸引力;姻亲关系;类同
功能:
指示 Activity 优先属于哪个任务。默认情况下,同一应用中的所有 Activity 彼此关联。 因此,默认情况下,同一应用中的所有 Activity 优先位于相同任务中。 不过,您可以修改 Activity 的默认关联。 在不同应用中定义的 Activity 可以共享关联,或者可为在同一应用中定义的 Activity 分配不同的任务关联。
设置位置
AndroidManifest.xml
<activity
android:name=".launchMode.LmFirstActivity"
android:label="Launch Mode"
android:taskAffinity="com.android.demos.jason.FIRST">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.android.demos.jason.myandroiddemos" />
</intent-filter>
</activity>
两种场合发挥作用
启动 Activity 的 Intent 包含 FLAG_ACTIVITY_NEW_TASK 标志,或者Manifest中定义为singleTask。
场景:
有些实体(如通知管理器)始终在外部任务中启动 Activity,而从不作为其自身的一部分启动 Activity,因此它们始终将 FLAG_ACTIVITY_NEW_TASK 放入传递给 startActivity() 的 Intent 中
Activity 将其 allowTaskReparenting 属性设置为 “true”。
场景:
在这种情况下,Activity 可以从其启动的任务移动到与其具有关联的任务(如果该任务出现在前台)。
例如,假设将报告所选城市天气状况的 Activity 定义为旅行应用的一部分。 它与同一应用中的其他 Activity 具有相同的关联(默认应用关联),并允许利用此属性重定父级。当您的一个 Activity 启动天气预报 Activity 时,它最初所属的任务与您的 Activity 相同。 但是,当旅行应用的任务出现在前台时,系统会将天气预报 Activity 重新分配给该任务并显示在其中。
其他
- 默认情况下,一个应用中的所有activity具有相同的taskAffinity,即应用程序的包名。我们可以通过设置不同的taskAffinity属性给应用中的activity分组,也可以把不同的 应用中的activity的taskAffinity设置成相同的值。
- 为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task。
- 一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity。
- 在standard模式下,即使taskAffinity不一样,仍旧会被分配到同一个Task下(实测),只有在SingleTask下设置与不设置有较大区别。
有用链接
Android Activity Launch Mode Example: Detailed Explaination
Understand Android Activity’s launchMode: standard, singleTop, singleTask and singleInstance