不同的事件(一些由用户触发和一些由系统触发)可能会导致 Activity
从一种状态转换为另一种状态。本文档介绍了发生此类转换的一些常见情况以及如何处理这些转换。
如需详细了解 activity 状态,请参阅 activity 生命周期。如需了解 ViewModel
类如何帮助您管理 activity 生命周期,请参阅 ViewModel 概览。
配置发生了更改
有很多事件会触发配置更改。最突出的例子或许是屏幕方向在纵向与横向之间切换。其他可能导致配置更改的情况包括语言设置或输入设备的更改。
当发生配置更改时,系统会销毁并重新创建 activity。这会在原始 activity 实例中触发以下回调:
系统会创建一个新的 activity 实例,并触发以下回调:
您可以结合使用 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 界面状态,请参阅保存和恢复瞬时界面状态。