android Activity 的 Task Affinity lanchMode
l FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
l FLAG_ACTIVITY_SINGLE_TOP
主要的<activity>属性有:
l taskAffinity
l launchMode
l allowTaskReparenting
l clearTaskOnLaunch
l alwaysRetainTaskState
l finishOnTaskLaunch
默认情况下,一个应用程序中的所有 activity 都有一个 affinity–这让它们属于同一个 task。然而,每个 activity 可以通过<activity>中的 taskAffinity 属性设置单独的 affinity。不同应用程序中的 activity 可以共享同一个 affinity,同一个应用程序中的不同 activity 也可以设置成不同的 affinity。affinity 属性在 2 种情况下起作用:当启动 activity 的 Intent 对象包含 FLAG_ACTIVITY_NEW_TASK 标记,或当 activity 的 allowTaskReparenting 被设置成 true。
l?FLAG_ACTIVITY_NEW_TASK 标记
当传递给 startActivity()的 Intent 对象包含 FLAG_ACTIVITY_NEW_TASK 标记时,系统会为需要启动的 activity 寻找与当前 activity 不同的 task。如果要启动的 activity 的 affinity 属性与当前所有的 task 的 affinity 属性都不相同,系统会新建一个带那个 affinity 属性的 task,并将要启动的 activity 压到新建的 task 栈中;否则将 activity 压入那个 affinity 属性相同的栈中。
l?allowTaskReparenting 属性
如果一个 activity 的 allowTaskReparenting 属性为 true,那么它可以从一个 task(TASK1)移到另外一个有相同 affinity 的 task(TASK2)中(TASK2 带到前台时)。
如果一个.apk 文件从用户角度来看包含了多个“应用程序”,你可能需要对那些 activity 赋不同的 affinity 值。
2、运行模式
activity 的 launchMode 属性可以有四种值:
l “standard” (默认)
l “singleTop“
l “singleTask“
l “singleInstance“
这 4 种模式可以按 4 种分类来区分,以下假设位于 task1 中的 activity1 启动 activity2:
<table cellspacing="0" cellpadding="0" border="1" style="color:rgb(0,0,0); font-family:Helvetica,Tahoma,Arial,sans-serif; font-size:14px; line-height:25.1875px"><tbody><tr><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"><strong>模式\分类</strong></p></td><td width="159" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"><strong>包容 activity2 的 task</strong></p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"><strong>一个 activity 是否允许有多个实例</strong></p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"><strong>activity 是否允许有其它 activity 共存于一个 task</strong></p></td><td width="199" style="font-size:1em"><p styl
e="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"><strong>对于新的 intent,是否总是实例化 activity 对象</strong></p></td></tr><tr><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">standard</p></td><td width="159" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">如果不包含 FLAG_ACTIVITY_NEW_TASK 标记,则 activity2 放入 task1,否则按前面讲述的规则为 activity2 选择 task</p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">可被多次实例化,同一个 task 的不同的实例可位于不同的 task 中,每个 task 也可包含多个实例</p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">允许</p></td><td width="199" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">是的。当接收到新的 intent 时,总是会生成新的 activity 对象。</p></td></tr><tr><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">singleTop</p></td><td width="159" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">同 standard</p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">同 standard</p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">允许</p></td><td width="199" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">已存在的 activity 对象,如果位于目标 task 的栈顶,则该 activity 被重用,如果它不位于栈顶,则会实例化新的 activity 对象</p></td></tr><tr><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">singleTask</p></td><td width="159" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">将 activity2 放到 task1 栈顶</p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">不能有多个实例。由于该模式下 activity 总是位于栈顶,所以 actvity 在同一个设备里至多只有一个实例</p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">允许。singleTask 模式的 activity 总是位于栈底位置。目标 activity 实例已存在时,如果该实例刚好位于 task 栈顶,则接收 intent,否则到来的 intent 将会被丢弃,但该可以响应该 intent 的那个 activity 所在的 task 将会被移到前台。</p></td><td width="199" style="font-size:1em"> </td></tr><tr><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">singleInstance</p></td><td width="159" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">同 singleTask</p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">同 singleTask</p></td><td width="114" style="font-size:1em"><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">不允许与其它 activity 共存于一个 task。如果 activity1 的运行在该模式下,则 activity2 一定与 activity1 位于不同的 task</p></td><td width="199" style="font-size:1em"> </td></tr></tbody></table>
对于新到的 intent,如果是由新创建的 activity 对象来接收,则用户可以通过返回键回到之前的 activity;如果是由已存在的 activity 来接收,则用户无法通过返回键返回到接收 intent 之前的状态。
3、清空栈
当用户长时间离开 task(当前 task 被转移到后台)时,系统会清除 task 中栈底 activity 外的所有 activity。这样,当用户返回到 task 时,只留下那个 task 最初始的 activity 了。
这是默认的情况,<activity>中有些属性可以改变这种行为。
l alwaysRetainTaskState 属性
评论