任务是用户在尝试执行某些操作时与之互动的一系列 activity 执行某些操作这些 activity 排列在一个称为 返回堆栈,按每个 activity 打开的顺序排列。
例如,电子邮件应用 可能有一个 activity 来显示新邮件列表。当用户选择 消息,系统会打开一个新的活动来查看该消息。这项新活动已添加 返回堆栈。然后,当用户点按“返回”或做出“返回”手势时,这个新 activity 从堆栈中弹出
任务及其返回堆栈的生命周期
大多数任务都从设备主屏幕上启动。当用户触摸屏幕时 应用启动器中或主屏幕上的应用或快捷方式的图标; 该应用的任务进入前台。如果应用程序不存在任务,则 系统会创建一项新任务,并且主 activity 作为堆栈中的根 activity。
在当前 activity 启动另一个 activity 时,新 activity 会推送到顶部 并且会获得焦点上一个 activity 仍保留在堆栈中, 停止。当某个 activity 停止时,系统会保留其 界面。当用户执行返回操作时,当前 activity 为 从堆栈顶部弹出并销毁。通过 之前的 activity 会恢复,而其界面的前一状态会恢复。
以下位置中的活动: 从未被重新排列,只会按原样推送到堆栈中和从堆栈中弹出 由当前 activity 启动并被用户关闭 返回按钮或手势因此,返回堆栈以 采用后进先出的对象结构。图 1 显示了一个带有 被推送到返回堆栈并从返回堆栈弹出的 activity。

当用户继续点按或做出“返回”手势时,堆栈中的每个 activity 会弹出上一个窗口,直到用户返回首页 屏幕或任务开始时正在运行的任何 activity。当所有 从堆栈中移除 activity,则任务将不存在。
根启动器 activity 的返回点按行为
根启动器 activity 是声明 intent 的 activity
和过滤条件
ACTION_MAIN
和
CATEGORY_LAUNCHER
。
这些 activity 独一无二,因为它们充当着从 Google Play 下载的
应用启动器,用于启动任务。
当用户从根启动器 activity 中点按或做出“返回”手势时,系统 处理事件的方式会有所不同,具体取决于 设备正在运行。
- Android 11 及更低版本上的系统行为
- 系统完成 activity。
- Android 12 及更高版本上的系统行为
系统会将 activity 及其任务移���后台,而不是 以及结束活动此行为与默认系统行为一致, 使用主屏幕按钮或手势离开应用。
在大多数情况下,这种行为意味着用户可以更快地恢复您的应用 而不是从温状态开始 必须从冷启动时间 状态。
如果您需要提供自定义返回导航, 我们建议使用 AndroidX Activity API,而不是替换
onBackPressed()
。AndroidX Activity API 会自动遵循 如果没有组件拦截系统,则相应的系统行为 点按背面。但是,如果您的应用替换
onBackPressed()
用于处理 返回导航并完成 activity,更新您的实现以调用 一直到super.onBackPressed()
,而不是完成。正在呼叫super.onBackPressed()
在以下情况下会将 activity 及其任务移至后台: 并且能为用户提供更加一致的导航体验 。
后台任务和前台任务

任务是一个有机整体,在用户开始 新任务或转到主屏幕。在后台运行时,所有 activity 停止,但任务的返回堆栈仍然保持不变,即任务 失去焦点,如图 2 所示。答 然后,任务可以返回到前台,以便用户可以从离开的位置继续 关闭。
假设当前任��� A 的以下任务流程 其堆栈中有三个 activity,包括当前 activity 下的两个:
用户使用主屏幕按钮或手势,然后从 应用启动器。
出现主屏幕时,任务 A 进入后台。当新的 应用启动时,系统会为该应用启动一个具有自己的堆栈的任务(任务 B) 活动数。
与该应用互动后,用户再次返回主屏幕并选择 应用程序。
现在,任务 A 进入前台,其堆栈中的所有三个 activity 并且堆栈顶部的 activity 将恢复。此时, 用户还可以通过前往主屏幕并选择应用图标来切换回任务 B 或是从最近使用的应用列表中 screen。
多个 activity 实例

由于返回堆栈中的 activity 永远不会重新排列,因此如果您的应用 可让用户从多个 activity 启动特定 activity,新的 创建该 activity 的实例并将其推送到堆栈,而不是 将之前该 activity 的所有实例置于顶部。因此, 应用中的 activity 可能会多次实例化,即使 如图 3 所示。
如果用户使用“返回”按钮向后导航 按钮或手势,activity 实例就会按其顺序显示 每个对象都有自己的界面状态。不过,您可以将此 行为。了解 有关详情,请参阅管理 任务。
多窗口环境
当应用在多窗口模式中同时运行时 环境,在 Android 7.0 (API) 中受支持 级别 24)及更高版本,系统会单独管理每个窗口的任务。每个 窗口中可以包含多个任务同样,在 Android 设备上运行的 Android 应用也应如此 Chromebook:系统会在 按窗口统计
生命周期回顾
Activity 和任务的默认行为总结如下:
当 activity A 启动 activity B 时,activity A 会停止,但系统会 保留其状态,例如滚动位置和输入到表单中的任何文本。如果 用户在 activity B、activity A 中点按或使用“返回”手势 恢复并恢复其状态
当用户使用主屏幕按钮或手势离开任务时,当前的 activity 会停止,其任务会转到后台。系统会保留 任务中每个 activity 的状态。如果用户稍后通过以下方法来恢复任务: 选择开始该任务的启动器图标时,任务会进入 在前台运行,并在堆栈顶部恢复 activity。
如果用户点按“返回”或做出“返回”手势,当前 activity 会从 堆栈并将其销毁堆栈中的上一个 activity 会恢复。时间 当 activity 被销毁时,系统不会保留该 activity 的状态。
此行为与根启动器 activity 不同 当应用在搭载 Android 12 或更高版本的设备上运行时。
Activity 可以多次实例化,甚至是从其他任务对其进行实例化。
管理任务
Android 通过以下方式管理任务和返回堆栈: 所有 activity 都在同一任务中��继启动,最后一个为第一个, 输出堆栈。这对于大多数应用都非常有效,您通常无需担心 activity 与任务的关联方式,或任务在后端的存在方式 堆栈。
不过,您可能会决定要中断正常行为。 例如,您可能希望应用中的某个 activity 在 activity 被触发时启动新任务, 开始, 而不是放置在当前任务中。或者,当您启动 则您可能需要调出它的现有实例,而不是 在返回堆栈之上创建新实例的方法。或者,您可能 希望返回堆栈中清除除根 activity 之外的所有 activity 当用户离开任务时触发。
您可以使用
<activity>
清单元素
和标记
startActivity()
。
以下是可用于管理任务的主要 <activity>
属性:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch
以下是您可以使用的主要 intent 标志:
以下部分讨论如何使用这些清单属性 和 intent 标志来定义 activity 与任务的关联方式以及 在返回堆栈中的行为
此外,还讨论了与任务和活动 在“最近使用的应用”屏幕中进行显示和管理。通常,您可以让 系统定义任务和 activity 在 “最近使用的应用”屏幕,您无需修改此行为。有关 信息,请参阅“最近使用的应用”屏幕。
定义启动模式
通过启动模式,您可以定义如何关联新的 activity 实例 与当前任务相关联。您可以通过两种方式定义启动模式 :
-
在清单文件中声明 Activity 时,您可以指定 activity 在启动时会与任务相关联。
-
致电后
startActivity()
、 可以在Intent
,用于声明 新 activity 将与当前任务相关联。
因此,如果 activity A 启动 activity B,activity B 可以在其清单中定义 activity A 可以使用 intent 标志, 请求 activity B 如何与当前任务关联。
如果两者 activity 定义了 activity B 与任务的关联方式,然后 activity A 的 请求(如 intent 中所定义)优先于 activity B 的请求,如 在其清单中定义的任何订单。
使用清单文件定义启动模式
在清单文件中声明 Activity 时,您可以指定
使用
<activity>
元素的
launchMode
属性。
您可以为 launchMode
属性指定五种启动模式:
"standard"
- 默认模式。系统会在任务中创建新的 activity 实例 以及将 intent 传递给它。活动可以是 实例化多次,每个实例可以属于不同的任务,以及 一个任务可以有多个实例。
"singleTop"
- 如果当前任务的顶部已存在 activity 的实例,
系统会通过调用
onNewIntent()
方法,而不是创建新的 Activity 实例。此活动为 实例化多次,每个实例可以属于不同的任务, 一个任务可以有多个实例(但前提是顶部的 activity 不是 activity 的现有实例)。
例如,假设任务的返回堆栈由根 activity A 和 activity B、activity C 和 activity D 在顶部(因此堆栈为 A-B-C-D,D 在顶部)。intent 。如果 D 具有默认的
"standard"
启动 模式,系统会启动该类的新实例,并且堆栈会变为 A-B-C-D-D。 不过,如果 D 的启动模式为"singleTop"
,则 D 的现有实例 通过onNewIntent()
接收 intent, 因为它位于堆栈顶部,而堆栈仍旧是 A-B-C-D。如果 另一方面 intent 到达类型 B 的 activity,则系统会将 B 的新实例添加到 堆栈中,即使其启动模式为"singleTop"
。"singleTask"
- 系统会在新任务的根位置创建 activity 或找到
具有同一相似性的现有任务上的 activity。如果
已存在,则系统会将
intent(通过调用其
onNewIntent()
方法,而不是创建新实例。同时,所有其他 其上的 activity 会被销毁。 。
"singleInstance"
。- 此行为与
"singleTask"
相同,只是系统不会启动任何其他 将 activity 放入包含该实例的任务中。activity 始终是 是其任务中的唯一一个成员。由此活动启动的所有活动都会在 一个单独的任务。
"singleInstancePerTask"
。- activity 只能作为任务的根 activity(第一个 activity)运行
activity,因此只能有一个实例
此 activity 的实际情况。与
singleTask
启动模式相比,以下代码 在不同任务的多个实例中启动 activity,如果FLAG_ACTIVITY_MULTIPLE_TASK
或FLAG_ACTIVITY_NEW_DOCUMENT
标志已设置。
再举一个例子,Android 浏览器应用声明,网络浏览器
通过指定 singleTask
,activity 始终在自己的任务中打开
<activity>
中的启动模式
元素。这意味着,如果您的应用发出用于打开 Android
浏览器时,其 activity 不会与您的应用放在同一任务中。相反,
将为浏览器启动新任务;如果浏览器已有任务
在后台运行时,系统会将该任务上移一层以处理新的
intent。
无论 activity 是在新任务中启动还是在同一任务中启动,都是如此
启动它的 activity 时,返回按钮和手势始终会
转至上一个 activity。不过,如果你启动一个
指定了
singleTask
启动模式,并且该 activity 的一个实例存在于
后台任务,那么整个任务都会转至前台。此时,
返回堆栈包含在
堆栈顶部图 4 显示了这种情况。

"singleTask"
会添加到返回堆栈中。如果活动
已经属于具有自己的返回堆栈的后台任务,那么
整个返回堆栈���会向前推进,
任务。如需详细了解如何在清单文件中使用启动模式,请参阅
<activity>
元素文档。
使用 Intent 标志定义启动模式
启动 activity 时,您可以修改 activity 的默认关联
通过在向其传递的 intent 中添加标志,
startActivity()
。
可用于修改默认行为的标志如下:
FLAG_ACTIVITY_NEW_TASK
系统会在新任务中启动 activity。如果已有为 activity 启动后,系统会将该任务转到前台运行,并向其发出 恢复最后状态,并且 activity 在
onNewIntent()
。这会生成与
"singleTask"
讨论了launchMode
值 。FLAG_ACTIVITY_SINGLE_TOP
如果正在启动的 activity 是当前 activity,则位于返回的顶部 则现有实例会收到
onNewIntent()
,而不是创建新的 activity 实例。这会生成与
"singleTop"
launchMode
值。FLAG_ACTIVITY_CLEAR_TOP
如果要启动的 activity 已在当前任务中运行, 则系统不会启动该 activity 的新实例,而是会 系统会销毁其上面的所有其他 activity。其意图是 传递到 Activity 的已恢复实例(现在位于顶层)
onNewIntent()
。launchMode
属性没有可产生此行为的值。FLAG_ACTIVITY_CLEAR_TOP
最常与以下元素结合使用:FLAG_ACTIVITY_NEW_TASK
。这些标志组合使用时 找到另一个任务中的现有 activity,并将其放到某个位置 响应意图。"standard"
处理亲和性
“亲和性”表示 activity“首选”哪项任务哪些对象。修改者 默认情况下,同一应用中的所有 activity 彼此相似: 他们“更喜欢”位于同一任务中。
不过,您可以修改 activity 的默认相似性。定义的 activity 在不同应用内可以具有共同的兴趣相似受众群体,并且在同一应用中定义的 activity 可以分配不同的任务相似性。
您可以使用 taskAffinity
修改 activity 的相似性
<activity>
的属性
元素。
taskAffinity
属性接受的字符串值必须不同于
默认软件包名称
在 <manifest>
中声明
元素,因为系统会使用该名称标识默认任务
用户的应用体验
亲和性可在两种情况下发挥作用:
当启动 Activity 的 Intent 包含
FLAG_ACTIVITY_NEW_TASK
标志。默认情况下,新 activity 会启动到该 activity 的任务中 名为
startActivity()
。 它将被推送到与调用方相同的返回堆栈中。不过,如果传递给
startActivity()
的 intent 包含FLAG_ACTIVITY_NEW_TASK
标志,系统会查找其他任务来存放新 activity。通常情况下 这是一个新任务不过,不一定非要这么做。如果有 具有与新 activity 具有相同相似性的现有任务,即 activity 启动到该任务中。如果不存在,则会启动一个新任务。如果此标志导致 Activity 启动新任务,并且用户使用 使用主屏幕按钮或手势离开主屏幕,则必须为用户提供某种方式 返回到任务有些实体(例如通知管理器) 始终在外部任务中启动 activity,而不是作为其自身的一部分启动,因此 它们始终将
FLAG_ACTIVITY_NEW_TASK
放入传递给它们的 intent 中startActivity()
。如果外部实体可能 使用此标志可以调用您的 activity,请注意,用户具有 可让您更轻松地 已启动的任务,例如带有启动器图标, 该任务包含
CATEGORY_LAUNCHER
intent 过滤器。如需了解详情,请参阅启动任务部分。当 activity 具有
allowTaskReparenting
时 属性设置为"true"
。在这种情况下,activity 可以从其启动的任务移至其所在的任务 该任务在前台运行。
例如,假设一个 activity 报告天气状况, 选定城市定义为旅游应用的一部分。具有相同的亲和性 默认应用亲和性 通过此属性更改父项。
当您的某个 activity 启动 它最初同属于您的 活动。但是,当旅行应用的任务进入前台时, 天气预报活动将被重新分配给该任务,并显示在其中。
清除返回堆栈
如果用户长时间离开任务,系统会清除所有 根 activity 之外的 activity。当用户返回任务时 只会恢复根 activity。这取决于 我们假设 用户放弃正在做的操作的时间越来越长 然后返回任务以开始新的操作。
您可以使用下列几个 Activity 属性修改此行为:
alwaysRetainTaskState
- 在任务的根 activity 中将此属性设为
"true"
时, 而不会发生上述默认行为任务会保留所有 即使是在很长时间过后仍出现在堆栈中的 activity。 clearTaskOnLaunch
在任务的根 activity 中将此属性设置为
"true"
时,任务 每当用户离开任务时,系统都会清除到根 activity, 返回给它。也就是说,alwaysRetainTaskState
。通过 用户始终会返回到任务的初始状态, 任务。 。
finishOnTaskLaunch
此属性类似于
clearTaskOnLaunch
, 但它只对单个 activity 运行,而不是对整个任务执行操作。还会导致 任何要完成的 activity(根 activity 除外)。设置为"true"
时,activity 仍是任务的一部分,但仅限于当前会话。 如果用户离开任务再返回,该任务将不复存在。
启动任务
您可以通过向 activity 提供 intent 将其设为任务的入口点
将 "android.intent.action.MAIN"
作为指定操作的过滤器,
指定类别为 "android.intent.category.LAUNCHER"
:
<activity ... >
<intent-filter ... >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
...
</activity>
此类 intent 过滤器会导致 activity 的图标和标签 显示在应用启动器中,让用户能够启动 activity 并 在启动后随时返回到创建的任务。
第二项能力非常重要。用户必须能够在离开任务后
以便稍后使用此 activity 启动器返回该 activity。因此,请仅使用
二
用于将 activity 标记为始终启动任务的启动模式,"singleTask"
和 "singleInstance"
,当 activity 具有
ACTION_MAIN
和
CATEGORY_LAUNCHER
过滤。
例如,想象一下,如果缺少过滤器,会发生什么情况:
intent 会启动 "singleTask"
activity,从而启动一个新任务,而用户
花一些时间来完成这项任务。然后,用户使用主屏幕按钮或
手势。此时,该任务会转到后台,不再可见。现在,用户
无法返回到该任务,因为它未在应用中表示
启动器。
对于那些您不想让用户返回
activity,请设置 <activity>
元素的 finishOnTaskLaunch
发送至 "true"
。如需了解详情,请参阅清除返回堆栈部分。
有关如何表示和管理任务和活动的更多信息 最近使用的应用 screen。