不同的事件(一些由用户触发,一些由系统触发)会导致 Activity
从一种状态转换到另一种状态。本文档描述了一些此类转换发生的一些常见情况以及如何处理这些转换。
有关活动状态的更多信息,请参阅 活动生命周期。要了解 ViewModel
类如何帮助您管理活动生命周期,请参阅 ViewModel 概述。
发生配置更改
有许多事件可以触发配置更改。也许最突出的例子是在纵向和横向方向之间的更改。其他可能导致配置更改的情况包括语言设置或输入设备的更改。
当发生配置更改时,活动将被销毁并重新创建。这将触发原始活动实例中的以下回调
将创建一个新的活动实例,并触发以下回调
使用 ViewModel
实例、onSaveInstanceState()
方法或持久性本地存储的组合来跨配置更改保留活动的 UI 状态。决定如何组合这些选项取决于 UI 数据的复杂性、应用的用例以及对检索速度与内存使用量的考虑。有关保存活动 UI 状态的更多信息,请参阅 保存 UI 状态。
处理多窗口情况
当应用进入多窗口模式(在 Android 7.0(API 级别 24)及更高版本中可用)时,系统会通知正在运行的活动配置更改,从而经历前面描述的生命周期转换。
如果应用已经在多窗口模式下并调整大小,也会发生此行为。您的活动可以自行处理配置更改,也可以允许系统销毁活动并使用新尺寸重新创建它。
有关多窗口生命周期的更多信息,请参阅多窗口生命周期在多窗口支持页面中的说明。
在多窗口模式下,尽管有两个应用对用户可见,但只有用户正在交互的应用处于前台并拥有焦点。该活动处于恢复状态,而另一个窗口中的应用处于暂停状态。
当用户从应用 A 切换到应用 B 时,系统会调用应用 A 上的onPause()
和应用 B 上的onResume()
。每次用户在应用之间切换时,它都会在这两种方法之间切换。
有关多窗口模式的更多详细信息,请参阅多窗口支持。
活动或对话框显示在前台
如果新的活动或对话框显示在前台,获取焦点并部分覆盖正在进行的活动,则被覆盖的活动将失去焦点并进入暂停状态。然后,系统会调用其上的onPause()
。
当被覆盖的活动返回到前台并重新获得焦点时,系统会调用onResume()
。
如果新的活动或对话框显示在前台,获取焦点并完全覆盖正在进行的活动,则被覆盖的活动将失去焦点并进入停止状态。然后,系统会快速连续地调用onPause()
和onStop()
。
当被覆盖活动的同一实例返回到前台时,系统会对该活动调用onRestart()
、onStart()
和onResume()
。如果它是进入后台的被覆盖活动的新的实例,则系统不会调用onRestart()
,仅调用onStart()
和onResume()
。
用户点击或手势返回
如果活动处于前台并且用户点击或手势返回,则活动将通过onPause()
、onStop()
和onDestroy()
回调进行转换。活动被销毁并从返回堆栈中移除。
默认情况下,在这种情况下,onSaveInstanceState()
回调不会触发。此行为假设用户点击返回时不期望返回到活动的同一实例。
但是,您可以覆盖onBackPressed()
方法以实现自定义行为,例如显示一个对话框,询问用户是否确认要退出您的应用。
如果您覆盖了onBackPressed()
方法,我们强烈建议您仍然从覆盖的方法中调用super.onBackPressed()
。否则,系统的返回行为可能会让用户感到不适。
系统终止应用进程
如果应用处于后台并且系统需要为前台应用释放内存,则系统可以终止后台应用。当系统终止应用时,不能保证应用中会调用onDestroy()
。
要了解有关系统如何决定销毁哪些进程的更多信息,请阅读活动状态和从内存中弹出和进程和应用生命周期。
要了解如何在系统终止应用进程时保存活动 UI 状态,请参阅保存和恢复瞬态 UI 状态。