Android中的任务和返回栈
在做一项工作时,用户参与一项任务,这是一组动作。活动按照它们在称为后堆栈的堆栈中打开的顺序堆叠。例如,电子邮件应用程序中的一项操作可能是显示新消息列表。当用户选择一条消息时,会出现一个新的活动,用户可以在其中阅读该消息。这个新动作已被发送到队列的后面。当用户单击后退按钮时,新操作完成并从堆栈中删除。当多个应用程序在多窗口环境中运行时,Android 7.0(API 级别 24)及更高版本允许,系统为每个窗口单独维护任务;每个窗口可能包含多个任务。该系统为在 Chromebook 上运行的 Android 应用程序按窗口组织任务或任务组。
![](https://mangodoc.oss-cn-beijing.aliyuncs.com/geek8geeks/Task_and_Back_Stack_in_Android_0.jpg)
图 1. 了解后台堆栈
对于大多数任务,设备的主屏幕是起点。当用户点击应用程序启动器中的图标(或主屏幕上的快捷方式)时,应用程序的工作会被带到最前面。如果应用程序不存在任务(因为它最近没有使用过),则会创建一个新任务,并将应用程序的“主”活动作为堆栈的根活动打开。
当当前活动切换到新活动时,新活动被推到堆栈顶部并控制注意力。前面的动作仍在堆栈中,但不再处于活动状态。当任务完成时,系统会保存用户界面的当前状态。当用户点击后退按钮时,当前活动从堆栈顶部拔出(活动被销毁),并且先前的活动重新启动(其 UI 的先前状态被恢复)。堆栈中的 Activity 仅被压入堆栈和从堆栈中弹出——在当前 Activity 启动时压入堆栈,并在用户使用“后退”按钮退出时弹出。因此,后栈是一种“后进先出”的对象结构。图 1 使用时间线描述了这种行为,该时间线显示了活动的进展以及每个时间点的当前回退堆栈。
背压会发生什么?
如果用户反复按 Back,堆栈中的每个活动都会弹出以显示它之前的活动,直到用户返回主屏幕(或返回到任务开始时正在运行的任何活动)。从堆栈中删除所有操作后,该任务不再处于活动状态。
![](https://mangodoc.oss-cn-beijing.aliyuncs.com/geek8geeks/Task_and_Back_Stack_in_Android_1.jpg)
图 2. 失去焦点
任务是一个逻辑单元,当用户开始一项新任务或按下主页按钮返回主页屏幕时,它可能会被发送到“后台”。任务中的所有操作都在后台暂停,但任务的后台堆栈保持不变——任务刚刚失去焦点,而另一个任务正在执行,如图 2 所示。然后可以将任务带回“前台”,允许用户从中断的地方继续工作。假设当前任务(任务 A)在其堆栈中包含三个活动,其中两个在当前活动之下。用户点击 Home 按钮,然后打开应用程序启动器并选择一个新应用程序。当主屏幕出现时,任务 A 被推到后台。当一个新的应用程序启动时,系统会为它创建一个任务(任务 B),它有自己的一组活动。与该应用程序交互后,用户返回主页并选择首先启动任务 A 的应用程序。任务 A 现在出现在最前面,堆栈中的所有三个活动都完好无损,堆栈顶部的活动恢复了。用户现在可以通过导航到主页并选择启动任务的应用程序图标(或从“最近”页面选择应用程序的任务)返回到任务 B。在 Android 上,这是多任务处理的一个示例。
因为如果您的应用程序允许用户从多个活动中启动特定活动,则后堆栈中的活动永远不会重新组织,因此会生成该活动的新实例并将其放置到堆栈中(而不是将活动的任何先前实例置于顶部) )。因此,您的应用程序中的单个活动可能会被多次调用(甚至来自不同的作业)。因此,如果用户使用 Back 按钮向后浏览,则 Activity 的每个实例都将按照访问它的顺序呈现(每个实例都有自己的 UI 状态)。但是,如果您不希望多次创建活动,则可以更改此行为。在管理任务部分,我们将介绍如何实现这一点。要描述活动和任务的默认行为,请考虑以下事项:
- Activity B 开始时,Activity A 被中断,但系统的状态被保留(例如滚动位置和输入到表单中的文本)。当用户在Activity B中按下Back按钮后返回到Activity A时,Activity A的状态就恢复了。
- 当用户通过点击 Home 按钮退出任务时,当前的活动将终止并且任务被置于后台。任务中的每个活动都保存在系统内存中。如果用户随后通过单击首先启动它的启动器图标继续它,则该任务将进入前台并恢复堆栈顶部的活动。
- 当前活动从堆栈中移除,并在用户点击后退按钮时删除。在堆栈中,恢复先前的操作。删除活动时,系统不会跟踪活动的状态。
即使来自其他任务,也可以多次实例化活动。
组织你的任务
对于大多数应用程序,Android 管理任务和后台堆栈的方式(通过将所有启动的活动按顺序放置在同一个任务中并在“后进先出”堆栈中)运行良好,您不必担心如何您的活动与任务或它们在后台堆栈中的显示方式相关。但是,您可以决定要偏离标准。也许您希望应用程序中的 Activity 启动一个新任务(而不是放置在当前任务中),或者您可能希望将现有的 Activity 实例向前推进(而不是在返回堆栈的顶部创建一个新实例)当用户离开任务时,或者您可能希望在用户离开任务时清除除根活动之外的所有活动。使用您发送到 startActivity 的 activity> manifest 元素中的特征和 Intent 中的标志,您可以执行所有这些操作以及更多操作。
以下标签可用于强制定义 Back Stack:
- 任务亲和
- 启动模式
- allowTaskReparenting
- clearTaskOnLaunch
- alwaysRetainTaskState
- 完成任务启动
XML
Java
Intent openIntent = new Intent(getApplicationContext(), GeeksforGeeksActivity.class);
openIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(openIntent);
GeekTip: When it comes to activities and tasks, most apps should not interfere with the usual behavior. If you decide that changing the default behaviors is important for your activity, proceed with caution and make sure to evaluate the usability of the activity during launch and while returning to it using the Back button from other activities and tasks. Be careful to check for navigational behaviors that are inconsistent with the user’s expectations.
任务的几个关键特征
创建新任务或单击主页按钮时,它会消失在背景中。然后通过单击启动器图标(这是我们之前讨论过的启动器图标的另一个函数)或从最近的屏幕中选择它,将作业带到最前面。当后台运行多个任务或用户长时间退出某个任务时,系统会清除该任务除根Activity之外的所有Activity,以释放内存。用户再次返回Task时只恢复根Activity
快速拍摄示例
Android 浏览器应用程序指定 Web 浏览器活动应始终在其自己的Task中启动。这意味着如果您的应用程序发出启动 Android 浏览器的意图,则该活动不会分配给与您的应用程序相同的任务。相反,如果浏览器当前有一个在后台运行的任务,则会为浏览器启动一个新任务,或者将现有任务向前移动以实现新意图。
如何使用Java添加不同的启动模式:
Java
Intent openIntent = new Intent(getApplicationContext(), GeeksforGeeksActivity.class);
openIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(openIntent);
就是这样!
这就是你如何掌握 Backstack 和 Tasks 的行为!