用户触发和系统触发的不同事件会导致 Activity
从一个状态转换到另一个状态。本文档介绍了发生此类转换的一些常见情况,以及如何处理这些转换。
有关 Activity 状态的详情,请参阅了解 Activity 生命周期。要了解如何借助 ViewModel
类来管理 Activity 生命周期,请参阅 了解 ViewModel 类。
配置发生了更改
有很多事件会触发配置更改。最显著的例子或许是横屏和竖屏之间的屏幕方向变化。其他情况,如语言或输入设备的改变等,也可能导致配置更改。
当配置发生更改时,Activity 会被销毁并重新创建。原始 Activity 实例将触发 onPause()
、onStop()
和 onDestroy()
回调。系统将创建新的 Activity 实例,并触发 onCreate()
、onStart()
和 onResume()
回调。
结合使用 ViewModels、onSaveInstanceState() 方法和/或持久性本地存储,可使 Activity 的界面状态在配置发生更改后保持不变。在决定这些选项的组合方式时,需要考虑界面数据的复杂程度、应用的用例以及检索速度与内存使用的权衡。有关保存 Activity 界面状态的详情,请参阅保存界面状态。
处理多窗口模式的情况
一旦应用进入多窗口模式(适用于 Android 7.0(API 级别 24)及更高级别),系统会向当前运行的 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()
回调。活动不仅会被销毁,还会从返回堆栈中移除。
需要注意的是,在这种情况下,默认不会触发 onSaveInstanceState()
回调。此行为基于的假设是,用户点按返回按钮时不期望返回 Activity 的同一实例。不过,您可以通过替换 onBackPressed()
方法实现某种自定义行为,例如“confirm-quit”对话框。
如果您替换 onBackPressed()
方法,我们仍然强烈建议您从被替换的方法调用 super.onBackPressed()
。否则,返回按钮的行为可能会让用户感觉突兀。
系统终止应用进程
如果某个应用处于后台并且系统需要为前台应用释放额外的内存,则系统可能会终止后台应用以释放更多内存。要详细了解系统如何确定要销毁哪些进程,请阅读 Activity 状态和从内存中弹出以及进程和应用生命周期。
要了解如何在系统终止您的应用进程时保存 Activity 界面状态,请参阅保存和恢复 Activity 状态。