Activity 状态变更

不同的事件(一些由用户触发和一些由系统触发)可能会导致 Activity 从一种状态转换为另一种状态。本文档介绍了发生此类转换的一些常见情况以及如何处理这些转换。

如需详细了解 activity 状态,请参阅 activity 生命周期。如需了解 ViewModel 类如何帮助您管理 activity 生命周期,请参阅 ViewModel 概览

配置发生了更改

有很多事件会触发配置更改。最突出的例子或许是屏幕方向在纵向与横向之间切换。其他可能导致配置更改的情况包括语言设置或输入设备的更改。

当发生配置更改时,系统会销毁并重新创建 activity。这会在原始 activity 实例中触发以下回调:

  1. onPause()
  2. onStop()
  3. onDestroy()

系统会创建一个新的 activity 实例,并触发以下回调:

  1. onCreate()
  2. onStart()
  3. onResume()

您可以结合使用 ViewModel 实例、onSaveInstanceState() 方法或永久性本地存储空间,以便在配置发生更改时保留 activity 的界面状态。在决定如何组合这些选项时,需要考虑界面数据的复杂程度、应用的用例以及检索速度与内存用量的权衡。如需详细了解如何保存 activity 界面状态,请参阅保存界面状态

处理多窗口模式的情况

当应用进入多窗口模式(适用于 Android 7.0(API 级别 24)及更高版本)时,系统会向正在运行的 activity 发出配置变更通知,从而完成上述生命周期转换。

如果已经处于多窗口模式的应用调整大小,也会出现此行为。您的 activity 可以自行处理配置变更,也可以允许系统销毁 activity,并以新的尺寸重新创建该 activity。

如需详细了解多窗口模式生命周期,请参阅多窗口模式支持页面中的多窗口模式生命周期说明。

在多窗口模式下,尽管有两个应用对用户可见,但只有用户与之互动的应用位于前台并具有焦点。该 activity 处于“已恢复”状态,而另一个窗口中的应用则处于“已暂停”状态。

当用户从应用 A 切换到应用 B 时,系统会对应用 A 调用 onPause(),对应用 B 调用 onResume()。每当用户在应用之间切换时,它都会在这两种方法之间切换。

如需详细了解多窗口模式,请参阅多窗口支持

Activity 或对话框显示在前台

如果新的 activity 或对话框出现在前台,使其获得焦点并部分覆盖正在进行的 activity,被覆盖的 activity 会失去焦点并进入“已暂停”状态。然后,系统会对其调用 onPause()

当被覆盖的 activity 返回前台并重新获得焦点时,系统会调用 onResume()

如果新的 activity 或对话框出现在前台,使其获得焦点并完全覆盖正在进行的 activity,被覆盖的 activity 会失去焦点并进入“已停止”状态。然后,系统会快速连续调用 onPause()onStop()

当被覆盖的 activity 的同一实例返回前台时,系统会对该 activity 调用 onRestart()onStart()onResume()。如果是被覆盖的 activity 的新实例进入后台,则系统不会调用 onRestart(),而只会调用 onStart()onResume()

用户点按或手势“返回”

如果某个 activity 位于前台,并且用户点按该 activity 或做出“返回”手势,该 activity 会通过 onPause()onStop()onDestroy() 回调进行转换。系统会销毁 activity 并将其从返回堆栈中移除。

默认情况下,在这种情况下,onSaveInstanceState() 回调不会触发。此行为假设用户点按“返回”按钮时不会返回同一 activity 实例。

不过,您可以替换 onBackPressed() 方法来实现自定义行为,例如显示一个对话框,要求用户确认是否要退出您的应用。

如果您替换 onBackPressed() 方法,我们强烈建议您仍然通过被替换的方法调用 super.onBackPressed()。否则,系统返回行为可能会给用户造成困扰。

系统终止应用进程

如果应用在后台运行,并且系统需要为前台应用释放内存,则可以终止后台应用。当系统终止某个应用时,无法保证会在应用中调用 onDestroy()

如需详细了解系统如何确定要销毁的进程,请参阅 activity 状态和从内存中弹出以及进程和应用生命周期

如需了解如何在系统终止应用进程时保存 activity 界面状态,请参阅保存和恢复瞬时界面状态