任务和返回栈
任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即“返回栈”)中。
设备主屏幕是大多数任务的起点。当用户触摸应用启动器中的图标(或主屏幕上的快捷键)时,该应用的任务将出现在前台。 如果应用不在任务(应用最近未曾使用)中,则会创建一个新任务,并且该应用的“主”Activity 将作为堆栈中的根 Activity 打开。
当前 Activity 启动另一个 Activity 时,该新 Activity 会被推送到堆栈顶部,成为焦点所在。 前一个 Activity 仍保留在堆栈中,但是处于停止状态。Activity 停止时,系统会保持其用户界面的当前状态。 用户按“返回”按钮时,当前 Activity 会从堆栈顶部弹出(Activity 被销毁),而前一个 Activity 恢复执行(恢复其 UI 的前一状态)。
堆栈中的 Activity 永远不会重新排列,仅推入和弹出堆栈:
由当前 Activity 启动时推入堆栈;用户使用“返回”按钮退出时弹出堆栈。 因此,返回栈以“后进先出”对象结构运行。
下图,通过时间线显示 Activity 之间的进度以及每个时间点的当前返回栈,直观呈现了这种行为。
如果用户继续按“返回”,堆栈中的相应 Activity 就会弹出,以显示前一个 Activity,直到用户返回主屏幕为止(或者,返回任务开始时正在运行的任意 Activity)。 当所有 Activity 均从堆栈中删除后,任务即不复存在。
PS,如果不清楚请移步:
http://blog.csdn.net/u011726984/article/details/49361345 (●’◡’●)
任务是一个有机整体,当用户开始新任务或通过“主页”按钮转到主屏幕时,可以移动到“后台”。 尽管在后台时,该任务中的所有 Activity 全部停止,但是任务的返回栈仍旧不变,也就是说,当另一个任务发生时,该任务仅仅失去焦点而已,如下图图所示。
注:后台可以同时运行多个任务。但是,如果用户同时运行多个后台任务,则系统可能会开始销毁后台 Activity,以回收内存资源,从而导致 Activity 状态丢失。
由于返回栈中的 Activity 永远不会重新排列,因此如果应用允许用户从多个 Activity 中启动特定 Activity,则会创建该 Activity 的新实例并推入堆栈中(而不是将 Activity 的任一先前实例置于顶部)。 因此,应用中的一个 Activity 可能会多次实例化(即使 Activity 来自不同的任务),如下图所示。
因此,如果用户使用“返回”按钮向后导航,则会按 Activity 每个实例的打开顺序显示这些实例(每个实例的 UI 状态各不相同)。 但是,如果您不希望 Activity 多次实例化,则可修改此行为。具体可看此文:
Activity 和任务的默认行为总结如下:
- 当 Activity A 启动 Activity B 时,Activity A 将会停止,但系统会保留其状态(例如,滚动位置和已输入表单中的文本)。如果用户在处于 Activity B 时按“返回”按钮,则 Activity A 将恢复其状态,继续执行。
- 用户通过按“主页”按钮离开任务时,当前 Activity 将停止且其任务会进入后台。 系统将保留任务中每个 Activity 的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则任务将出现在前台并恢复执行堆栈顶部的 Activity。
- 如果用户按“返回”按钮,则当前 Activity 会从堆栈弹出并被销毁。 堆栈中的前一个 Activity 恢复执行。销毁 Activity 时,系统绝对不会保留该 Activity 的状态。
- 即使来自其他任务,Activity 也可以多次实例化。
保存 Activity 状态
正如上文所述,当 Activity 停止时,系统的默认行为会保留其状态。 这样一来,当用户导航回到上一个 Activity 时,其用户界面与用户离开时一样。 但是,在 Activity 被销毁且必须重建时,您可以而且应当主动使用回调方法保留 Activity 的状态。
系统停止您的一个 Activity 时(例如,新 Activity 启动或任务转到前台),如果系统需要回收系统内存资源,则可能会完全销毁该 Activity。 发生这种情况时,有关该 Activity 状态的信息将会丢失。如果发生这种情况,系统仍会知道该 Activity 存在于返回栈中,但是当该 Activity 被置于堆栈顶部时,系统一定会重建 Activity(而不是恢复 Activity)。 为了避免用户的工作丢失,您应主动通过在 Activity 中实现 onSaveInstanceState()
回调方法来保留工作。
如需了解有关如何保存 Activity 状态的详细信息,请参阅此文:
http://blog.csdn.net/u011726984/article/details/49481539。
管理任务
定义 Activity 与任务的关联方式
定义launchMode
移步此文:
http://blog.csdn.net/u011726984/article/details/49456287
使用 Intent 标志
启动 Activity 时,您可以通过在传递给 startActivity() 的 Intent 中加入相应的标志,修改 Activity 与其任务的默认关联方式。可用于修改默认行为的标志包括:
1, FLAG_ACTIVITY_NEW_TASK
在新任务中启动 Activity。如果已为正在启动的 Activity 运行任务,则该任务会转到前台并恢复其最后状态,同时 Activity 会在 onNewIntent() 中收到新 Intent。
这会产生与 “singleTask” launchMode 值相同的行为。
2, FLAG_ACTIVITY_SINGLE_TOP
如果正在启动的 Activity 是当前 Activity(位于返回栈的顶部),则 现有实例会接收对 onNewIntent() 的调用,而不是创建 Activity 的新实例。
这会产生与 “singleTop” launchMode 值相同的行为。
3, FLAG_ACTIVITY_CLEAR_TOP
如果正在启动的 Activity 已在当前任务中运行,则会销毁当前任务顶部的所有 Activity,并通过 onNewIntent() 将此 Intent 传递给 Activity 已恢复的实例(现在位于顶部),而不是启动该 Activity 的新实例。
产生这种行为的 launchMode 属性没有值。
FLAG_ACTIVITY_CLEAR_TOP 通常与 FLAG_ACTIVITY_NEW_TASK 结合使用。一起使用时,通过这些标志,可以找到其他任务中的现有 Activity,并将其放入可从中响应 Intent 的位置。
注:如果指定 Activity 的启动模式为 “standard”,则该 Activity 也会从堆栈中删除,并在其位置启动一个新实例,以便处理传入的 Intent。 这是因为当启动模式为 “standard” 时,将始终为新 Intent 创建新实例。
清理返回栈
如果用户长时间离开任务,则系统会清除所有 Activity 的任务,根任务除外。 当用户再次返回到任务时,仅恢复根 Activity。系统这样做的原因是,经过很长一段时间后,用户可能已经放弃之前执行的操作,返回到任务是要开始执行新的操作。
可以使用下列几个 Activity 属性修改此行为:
1, alwaysRetainTaskState
如果在任务的根 Activity 中将此属性设置为 “true”,则不会发生刚才所述的默认行为。即使在很长一段时间后,任务仍将所有 Activity 保留在其堆栈中。
2, clearTaskOnLaunch
如果在任务的根 Activity 中将此属性设置为 “true”,则每当用户离开任务然后返回时,系统都会将堆栈清除到只剩下根 Activity。 换而言之,它与 alwaysRetainTaskState 正好相反。 即使只离开任务片刻时间,用户也始终会返回到任务的初始状态。
3, finishOnTaskLaunch
此属性类似于 clearTaskOnLaunch,但它对单个 Activity 起作用,而非整个任务。 此外,它还有可能会导致任何 Activity 停止,包括根 Activity。 设置为 “true” 时,Activity 仍是任务的一部分,但是仅限于当前会话。如果用户离开然后返回任务,则任务将不复存在。
如有不足或遗漏请评论指出,谢谢!(●’◡’●)
官方文档:
http://developer.android.com/guide/components/tasks-and-back-stack.html