对 Android Task 和 Back Stack 的理解

以下内容来自官方文档「Understand Tasks and Back Stack」的手动翻译

Task 是 用来完成一个具体操作的 Activities 的一个集合。「一个具体操作可以理解为一个应用的所有功能,或者认为指定的某个功能(例如应用里的购票功能,或者聊天功能等)所以这个 job 是个抽象概念」。这些 Activities 被组织在一个栈里,这个栈就是 Back Stack 啦,那么系统就会按照栈的数据结构来管理这些 Activities 。举个例子,一个邮件应用有一个 Activity 用来展示邮件列表,并通过点击某一条进入一个新的 Activity 来看邮件详情。这个详情页就会被入栈,用户看完邮件点击返回按钮时,详情页就会被销毁,并出栈。

对于支持多窗口的系统(Android 7.0 及以上)系统会各自管理各个窗口里的 Tasks。

当用户通过桌面的应用启动图标点击启动应用时,应用如果已经存在 Task 了,就会被调到前台用于展示里面的 Activity,如果没有,就会新建一个 Task。

在当前 Activity 启动另一个 Activity 后,新的 Activity 就会被添加到 Back Stack 并获得焦点。先前的 Activity 依然在栈里,只是不可见且不能操作(stopped)。当 Activity 不可见且不能操作时,系统会保存当前状态,当用户按返回键返回时,当前 Activity 会从栈顶出栈(这个 Activity 就销毁了)之前的 Activity 会重新展示(之前保存的状态也会恢复)。在栈里的 Activities 是不会自己重排的,只会按照栈的结构入栈或出栈——即在当前 Activity 启动新的 Activity 时入栈,在用户返回时出栈。因此,Back Stack 遵循的是“后进先出”的规则,「其实就是栈的数据维护规则」。图1就是按时间线展示了当前 Back Stack 里 Activities 的行为。


图 1.png

如果用户一直返回,Back Stack 就会一直做出栈操作,直到回退到桌面(或者回退到这个 Task 开始的地方),当 Task 里所有 Activity 都被移除销毁了,那么这个 Task 也就不在了。

当前 Task 在被用户通过打开新的应用或者切到桌面以前都是内聚的状态,「即都是一个整体,但是我觉得 Task 即使在后台也是一个整理啊,不太理解原意」。当 Task 在后台时,所有 Activity 都是停止状态(stopped),但 Back Stack 依然是完整的—— Task 已经失去了焦点并由其他 Task 获得,如图 2 所示。后台的 Task 可以回到前台,并恢复之前的状态。假设,例如当前 Task A 有 3 个 Activity 在 Back Stack 里——两个 Activity 在当前 Activity 下面,用户按了 Home 键并启动另一个应用。当切换到桌面时,Task A 就进入了后台,另一个应用就创建了一个 Task B。过了一会儿,用户又回到桌面并点击了原先那个应用图标,这时 Task A 又回到了前台,那 3 个 Activity 完整如初,并且栈顶 Activity 恢复原先的状态。同理,对 Task B 也是这样的。这是一个多 Task 的举例。


图 2.png

注意:虽然 Task 可以被保存在后台,但是如果后台有很多 Task,那就有可能造成系统资源不够,部分 Task 被回收调,如果考虑不周,那么这些 Task 里的 Activities 状态就丢了。

由于在 Back Stack 里的 Activities 不会被重排,因此如果用户通过不同的 Activity 启动了某个相同的 Activity,都会创建新的 Activity 实例并入栈(而不是把之前的 Activity 实例置顶)。因此,同一个 Activity 可能会实例化多次(甚至在不同 Task 里),如图 3 所示。用户按返回键返回时,Activity 实例就会按入栈的顺序倒叙展示。不过,如果不想让同一个 Activity 实例化多次,我们也是可以修改的,具体如何修改可以看看 Managing Tasks

总结一下 Activities 和 Tasks 的默认行为:

  • 当 Activity A 启动 Activity B 后,Activity A 就停止了,但系统保存了它的状态(比如滚动的位置,编辑框里的文本等)。如果用户在 Activity B 按了返回键,Activity A 就会重新展示并恢复之前的状态。
  • 当用户按了 Home 键,当前 Activity 就会停止,相应的 Task 就会进入后台。系统保存着 Task 里 Activities 的状态。如果用户稍后通过桌面的应用图标回到应用,那么 Task 会重新回到前台,并恢复 Activities 的状态,展示栈顶的 Activity。
  • 如果用户按了返回键,当前 Activity 就会停止,并从栈中出栈销毁。先前的 Activity 会被展示。当 Activity 被销毁后,系统就不会再保存它的状态了。
  • 不管是在同一个 Task 还是不同 Task,Activity 都可被实例化 N 次。「这里的不同 Task 我理解是,从别的 Task 里的 Activity 启动某个特定 Activity 并指定 Task 或不指定」

你可能感兴趣的:(对 Android Task 和 Back Stack 的理解)