Activity任务栈和启动模式及其使用场景

##Activity任务栈

在android中 , 应用内的Activity是被任务栈Task来统一管理 的,默认情况下,包含前台任务栈和后台任务栈,任务栈是遵循***后进先出***的原则.

当应用启动的时候,系统就会创建一个Task,所在的Task在前台任务栈,当我们点击Home键时,所在的Task也进入了后台任务栈,当所有的Activity都退出的时候,任务栈就清空了.通过launchMode可以改变这种规则。

##launchMode

Activity的启动模式主要是在AndroidManifest.xml文件中进行指定,或者通过Intent 的Flag属性进行指定.

<activity android:name="ActivityMain" android:launchMode="singleTask"/>

standard标准模式

每次激活Activity时都会创建Activity,并放入任务栈中,这是系统默认的启动模式.

例如: 栈中顺序是A B C D ,此时D通过Intent跳转到A,那么栈中结构就变成 A B C D A,点击返回按钮的 显示顺序是 D C B A,依次摧毁。

singleTop栈顶复用模式

如果在任务的栈顶正好存在该Activity的实例, 就重用该实例(调用栈顶Activity的onNewIntent()方法),否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。

例如:现在栈的情况为:A B C D,B和D的launchMode为singleTop,在D中启动Intent跳转到D,不会创建D的实例,此时栈的情况依然为:A B C D,如果通过Intent跳转到B,就会创建一个B的实例,此时的栈情况为:A B C D B

使用场景: 比如常见的推送消息点击进入的Activity,登录的栈顶Activity

###singleTask栈内复用模式

Task栈中只能有一个对应Activity的实例,如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。

  1. 例如:现在栈的情况为:A B C D,B的launchMode为singleTask,在D通过Intent跳转到B,此时的栈情况为:A B ,CD都被弹出销毁了,通常应用于Application的首页。
  1. 如果没有设置taskAffinity属性值,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,最终这个Activity实例会位于任务的堆栈顶端中。

使用场景: 利用singleTask的清空属性,通常用在其他应用调用我们应用的场景.

###singleInstance单实例模式

在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity的实例存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例。和singleTask的主要区别是在单独的任务栈中启动,通过这个Activity再打开的其它Activity会被放入到别的任务中

例如:Task栈1中结构为:A B C,C通过Intent跳转到了D(singleInstance),此时会存在两个任务栈,Task2 中结构为D,此时如果D通过Intent打开D,则不会创建D的实例,D跳转到C,则根据Task1中的launchMode来做不同的操作,如果C为singleTop,Task1种的栈情况依然为A B C,此时点击返回键也不会回到D

使用场景: 这种模式很少被使用。一些真正的用例是一个用于启动或应用程序的活动,你是100%肯定只有一个活动.

总结

launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task。

##Intent Flags

 Intent intent = new Intent(this, ActivityB.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);

Intent.FLAG_ACTIVITY_NEW_TASK

在Activity中使用此flag 需要和TaskAffinity属性配合使用,在非Activity中启动activity必须要使用此flag

例如:Task1中的任务栈:ABC,在C中启动D,如果D的Manifest指定了TaskAffinity属性,那么系统就会去寻找是否存在此TaskAffinity的任务栈,如果存在,则创建D的实例并压入栈中,如果不存在就会创建一个新的任务栈,并将此activity压入栈中,如果没有指定TaskAffinity属性,就和android:launchMode = standard效果相同。

Intent.FLAG_ACTIVITY_SINGLE_TOP

类似andoid:launchMode="singleTop"

Intent.FLAG_ACTIVITY_CLEAR_TOP

类似andoid:launchMode="singleTask"

这种FLAG启动的Activity会把要启动的Activity之上的Activity全部弹出栈空间。通常和Intent.FLAG_ACTIVITY_NEW_TASK一同使用,用于用于启动一个Task中的根Activity,它会把那个Task中任何运行的实例带入前台,然后清除它直到根Activity。

Intent.FLAG_ACTIVITY_NO_HISTORY

使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在task栈中。例如A B,在B中以这种模式启动C,C再启动D,则当前的task栈变成A B D。

清空回退栈

alwaysRetainTaskState

如果 task 中根 activity 的此属性设为 “true” ,则默认的清理方式不会进行。即使过了很长时间,task 中所有的 activity 也都会保留在栈中。

clearTaskOnLaunch

如果 task 中根 activity 的此属性设为 “true”,则只要用户离开并再次返回该 task,栈就会被清理至根 activity。

如果将首页Activity的这个属性设置为true,那么只要用户离开了首页,再次返回的时候就会将其上的所有其它Activity全部清销毁。也就是每次都从首页开始。

finishOnTaskLaunch

通过这个属性,当离开这个Activity所在的task,那么当用户再返回时,该Activity就会被finish掉。

##TaskAffinity

affinity 表示 activity 预期所处的 task 。 缺省情况下,同一个应用中的所有 activity 都拥有同一个 affinity 值。 因此,同一个应用中的所有 activity 默认都期望位于同一个 task 中。 不过,你可以修改 activity 默认的 affinity 值。 不同应用中的 activity 可以共享同一个 affinity 值,同一个应用中的 activity 也可以赋予不同的 task affinity 值。

affinity 使用场景

  • 当启动 activity 的 intent 包含了FLAG_ACTIVITY_NEW_TASK标志。见上文
  • 当一个 activity 的allowTaskReparenting属性设为 “true”。
  1. taskAffinity用于指定当前Activity所关联的Task,allowTaskReparenting用于配置是否允许该activity可以更换从属task,通常情况二者连在一起使用,用于实现把一个应用程序的Activity移到另一个应用程序的Task中。
  1. 举例: 一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着Affinity的Task中。如果e-mail中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为e-mail Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当e-mail Task再次进入前台时,就看不到它了。

参考[Android Heroes Reading Notes 4]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值