Android任务和返回栈简单总结

       任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即返回栈)中。一般情况下我们可以认为一个应用就是一个任务,并且这个应用启动的所有Activity会按照打开的顺序放入堆栈中即是这个任务对应的返回栈。

       手机的主屏幕是大多数任务的起点。当用户触摸应用启动器中的图标(或主屏幕上的快捷方式)时,该应用的任务将出现在前台。 如果应用不存在任务(应用最近未曾使用),则会创建一个新任务,并且该应用的“主”Activity 将作为堆栈中的根 Activity 打开。

       一般我们把任务分为两种:前台任务和后台任务。当用户开始新任务或通过“主页”按钮转到主屏幕时,当前任务被移动到“后台”。 尽管该任务在“后台”,任务中的所有 Activity 全部停止,但是任务的返回栈仍旧不变,也就是说,当任务被切换到“后台”时,该任务仅仅失去焦点而已。在必要的时候我们还是可以把这个任务切换到“前台”来。要注意的一个点就是,如果后台运行的任务太多的时候,系统可能会销毁后台 Activity,以回收内存资源,从而导致 Activity 状态丢失

任务返回栈的入栈:启动新的Activity。
任务返回栈的出栈:销毁栈顶的Activity(如BACK按键操作)。

一 任务的默认行为

       默认情况下,一个应用对应一个任务对应一个返回栈。如果应用之前没有被启动过,点击主屏幕应用启动器中的图标的时候会生成一个全新的任务,并且该应用的“主”Activity 将作为任务返回栈中的根 Activity 打开,之后依次打开的Activity会按照打开的顺序压入返回栈中。当按”BACK”键返回时,这些压入返回栈中的Activity会按照“后进先出”的原则依次出栈,恢复回退栈中前一个 Activity 的执行。

这里写图片描述

       默认情况下,用户通过按“HOME”按钮离开任务时,当前 Activity 将停止且当前Activity对应的任务会进入后台。 系统将保留任务中每个 Activity 的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则任务将出现在前台并恢复执行堆栈顶部的 Activity。

这里写图片描述

       默认情况下的行为总结如下:

  • Activity 可以被多次实例化不管Activity是不是有相同的taskAffinity(不管是来自当前任务的Activity还是其他任务的Activity)。
  • 如果用户按“返回”按钮,则当前 Activity 会从堆栈弹出并被销毁。 堆栈中的前一个 Activity 恢复执行。
  • 同一个入口的所有Activity都会放入同一个返回栈中。

二 任务的管理

       如上所述默认行为(将所有连续启动的 Activity 放入同一任务和“后进先出”堆栈中)非常适用于大多数应用,而您不必担心 Activity 如何与任务关联或者如何存在于返回栈中。 但是,有的时候您可能会决定要中断正常行为, 也许您希望应用中的 Activity 在启动时开始新任务(而不是放置在当前任务中);或者,当启动 Activity 时,您希望将其现有实例上移一层(而不是在返回栈的顶部创建新实例);或者,您希望在用户离开任务时,清除返回栈中除根 Activity 以外的所有其他 Activity。这个时候您就要控制任务和返回栈了,那就得上任务管理了。

一般通过两种方式来管理任务和返回栈:一是通过activity清单文件launchMode启动模式来管理,二是通过调用 startActivity() 时 Intent 中加入一个标志来管理,用于声明新 Activity 如何(或是否)与当前任务关联。

2.1 activity清单文件launchMode启动模式

launchMode 属性指定如何将 Activity 启动到任务中的指令。您可以分配给 launchMode 属性的启动模式共有四种:

  • standard(默认模式)
           系统在启动 Activity 的任务中创建 Activity 的新实例。Activity 可以多次实例化,而且每个实例均可属于不同的任务(不同的taskAffinity,不同的应用)。所有启动的Activity都会被加入到当前任务的返回栈中。

  • singleTop
           如果您要启动的Activity已经位于返回栈的顶部的时候,则系统会通过调用该Activity的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例。Activity 可以多次实例化(可以不是同一个应用的Activity)的前提是位于返回栈顶部的 Activity 并不是要启动的Activity 。

这里写图片描述

  • singleTask
           如果您要启动的Activity已存在于一个单独的任务中(不管是当前热任务还是其他的任务只要他存在),则系统会通过调用现有实例的 onNewIntent() 方法向其传送 Intent,而不是创建新实例。并且把该返回栈中该Activity之上的所有Activity弹出栈销毁掉同时切换到你启动的Activity的那个任务去。(同一个任务中的很好理解,我用图来表示不用任务中singleTask的情况)。
    这里写图片描述

  • singleInstance
           会把您要启动的Activity单独的放置在一个返回栈中,并且这个返回栈中只有这么一个Activity。如果这个Activity启动过(已经被放置在一个单独的返回栈当中)则系统会通过调用现有实例的 onNewIntent() 方法向其传送 Intent,而不是创建新实例。
    这里写图片描述

2.2 Intent flag标志:
  • FLAG_ACTIVITY_NEW_TASK:
           如果发起Activity和需要启动的Activity都属于同一个应用中(有相同的taskAffinity)。那么表现形式和“singleTask”launcheMode相同(如果需要启动的Activity之前已经被启动过了,那么需要启动的Activity会转到前台,弹出任务回退栈该Activity上面所有的Activity。如果需要启动的Activity没有被启动,则新建一个实例加入任务回退栈中)。
           如果发起Activity和需要启动的Activity不属于同一个应用中(不同的taskAffinity),那么需要启动的Activity会新建一个实例,并且加入到一个全新的任务回退栈中。

  • FLAG_ACTIVITY_SINGLE_TOP:
           表现形式和“singleTop”launcheMode相同。

  • FLAG_ACTIVITY_CLEAR_TOP:
           如果发起Activity和需要启动的Activity都属于同一个应用中(有相同的taskAffinity)。要启动的Activity已经在当前回退栈中了,则会把该Activity和他之上的所有Activity销毁掉,再重新实例化这个Activity,放入回退栈中。
           如果发起Activity和需要启动的Activity不属于同一个应用中(不同的taskAffinity),正常实例化Activity,放入当前回退栈中。

  • FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP:
           如果要启动的Activity已经存在不管是在当前任务还是其他后台任务中,都会把任务回退栈该Activity连同上面的所有Activity销毁掉,再重新实例化Activity放入之前Activity存在的任务回退栈中。
    这里写图片描述

三 处理任务关联

“关联”指示 Activity 优先属于哪个任务。默认情况下,同一应用中的所有 Activity 彼此关联属于同一个任务。 因此,默认情况下,同一应用中的所有 Activity 优先位于相同任务中。 但是有的时候,您可能要修改 Activity 的默认关联:在不同应用中定义的 Activity 可以共享关联,或者可为在同一应用中定义的 Activity 分配不同的任务关联。可以使用ManifestAndroid.xml文件中activity标签元素中的 taskAffinity 属性修改任何给定 Activity 的关联。

       affinity是指Activity的归属(Activity属于哪个回退栈)。这个属性表明Activity进入哪个回退栈当中去(注意这里说的是进入哪个回退栈,只是)。如果想变成现实那么的配合Intent flag的FLAG_ACTIVITY_NEW_TASK属性或者allowTaskReparenting属性来使用。

  • taskAffinity + Intent FLAG_ACTIVITY_NEW_TASK:
           如果要启动的Activity和被启动的Activity不属于同一个taskAffinity,那么被启动的Activity会被放入一个新的任务返回栈中。

  • taskAffinity + allowTaskReparenting:
           把allowTaskReparenting属性设置为true。Activity 可以从其启动的任务栈移动到与其具有关联的任务栈中(如果该任务出现在前台)。简单来说就是A应用启动了B应用的一个界面,这个时候切回到B应用(HOME键再点击B的luancher图标)这个时候这个页面会抽出来移动到B应用回退栈的顶部。
    这里写图片描述

四 清理返回栈

如果用户长时间离开任务,则系统会清除所有 Activity 的任务,根 Activity 除外。 当用户再次返回到任务时,仅恢复根Activity。系统这样做的原因是,经过很长一段时间后,用户可能已经放弃之前执行的操作,返回到任务是要开始执行新的操作。但是有的时候我们可以使用一些属性来更改这些行为。

  • alwaysRetainTaskState:如果在任务的根 Activity 中将此属性设置为 “true”,则不会发生刚才所述的默认行为。即使在很长一段时间后,任务仍将所有 Activity 保留在其堆栈中。

  • clearTaskOnLaunch:如果在任务的根 Activity 中将此属性设置为 “true”,则每当用户离开任务然后返回时,系统都会将堆栈清除到只剩下根 Activity。 换而言之,它与alwaysRetainTaskState 正好相反。 即使只离开任务片刻时间,用户也始终会返回到任务的初始状态。

  • finishOnTaskLaunch:此属性类似于 clearTaskOnLaunch,但它对单个 Activity 起作用,而非整个任务。 此外,它还有可能会导致任何 Activity 停止,包括根 Activity。 设置为 “true” 时,Activity 仍是任务的一部分,但是仅限于当前会话。如果用户离开然后返回任务,则任务将不复存在。

以上就是对Android任务和返回栈的简单总结。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值