Activity Lifecycle 是一组回调方法,Android 在 Activity 在状态之间转换时调用:创建、可见性、输入焦点、部分失去可见性、完全隐藏和销毁。系统管理应用程序每个屏幕的生命周期,从调用 onCreate() 开始到 onDestroy 结束。理解这些状态是 Android 应用程序稳定运行的强制性要求,因为方法之间转换处理不当会导致内存泄漏、用户数据丢失和意外崩溃。关于 Android 架构的更多信息,请阅读关于 Android 的综合文章。
要点
Activity Lifecycle(Activity 生命周期) — 是一个有限状态机,Android 应用程序的每个屏幕从创建到完全销毁都会经历这个过程。Android 系统根据用户操作管理此过程:打开应用程序、最小化、旋转屏幕、接听来电、在应用程序之间切换和结束操作。
理解生命周期对每个 Android 开发者来说都是必要的,因为系统可能在内存不足时随时销毁 Activity — 而应用程序必须正确恢复其状态。根据 Google Android Vitals (2025) 的数据,不处理 onSaveInstanceState() 中状态保存的应用程序在重新创建 Activity 时显示的崩溃次数多 42%。
生命周期包括六个主要的回调方法:onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()。此外还有 onRestart() 方法,当 Activity 从停止状态返回时,在 onStart() 之前调用。每个方法都有严格定义的目的和执行时间 — 系统按顺序调用它们,开发者可以重写其中任何一个来执行自己的逻辑。
生命周期可以分为三个关键阶段:整个生命周期(onCreate → onDestroy)、可见生命周期(onStart → onStop)和前台生命周期(onResume → onPause)。理解这三个层次有助于正确分配初始化和资源释放的代码。
每个生命周期方法执行严格定义的任务。系统按固定顺序调用它们,开发者应只重写特定逻辑所需的方法。不建议直接调用生命周期方法 — 这由 Android Runtime 处理。
启动应用程序时的典型顺序:onCreate → onStart → onResume。按下「返回」按钮时:onPause → onStop → onDestroy。最小化时:onPause → onStop,然后返回时:onRestart → onStart → onResume。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
super.onStart()
}
override fun onResume() {
super.onResume()
}
override fun onPause() {
super.onPause()
}
override fun onStop() {
super.onStop()
}
override fun onDestroy() {
super.onDestroy()
}
override fun onRestart() {
super.onRestart()
}
}
每个重写的方法 必须调用 super 版本 — 否则系统无法正确完成状态之间的转换。此规则已在 Android Developers 文档中确定,并由 Android Studio 的 lint 规则检查。
第一层 — 整个生命周期(entire lifetime):onCreate 和 onDestroy 之间的间隔。在此处进行一次性初始化和全局资源的最终释放。第二层 — 可见生命周期(visible lifetime):onStart 和 onStop 之间。Activity 在屏幕上可见,但可能被其他窗口部分遮挡。第三层 — 前台生命周期(foreground lifetime):onResume 和 onPause 之间。Activity 位于任务栈顶部并与用户交互。
onCreate() — Activity 生命周期的第一个也是唯一必需的方法。系统在创建 Activity 实例时调用一次。此方法接收 savedInstanceState: Bundle? 参数,其中包含之前保存的状态(如果 Activity 在销毁后重新创建)— 例如在屏幕旋转时。
在 onCreate 中执行以下任务:通过 setContentView() 传递布局资源来初始化用户界面,通过 findViewById() 绑定 View 元素,为 RecyclerView 和 ViewPager 设置适配器,从 savedInstanceState 恢复状态,初始化 ViewModel 和 LiveData,设置点击和手势监听器。方法应尽快完成 — 此处的长时间操作会阻塞第一帧的渲染,从而增加应用程序的启动时间。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)
val userNameText: TextView = findViewById(R.id.user_name)
val loadButton: Button = findViewById(R.id.load_button)
if (savedInstanceState != null) {
userNameText.text = savedInstanceState.getString("user_name")
}
loadButton.setOnClickListener {
loadUserProfile()
}
}
如果 Activity 是第一次创建,savedInstanceState 为 null。在屏幕旋转后重新创建时,Bundle 包含在 onSaveInstanceState() 中保存的数据。检查 null 是正确恢复 UI 而不会丢失用户输入数据的标准做法。
onStart() 在 onCreate() 之后或 onRestart() 之后立即调用,当 Activity 对用户变为可见时。在此状态下,Activity 尚未在前台,不能与用户交互,但其用户界面已在屏幕上可见。例如,在启动应用程序时,在 onStart 和 onResume 调用之间,系统渲染界面的第一帧。
在 onStart 方法中通常执行以下操作:启动在 Activity 可见时应运行的动画;绑定 BroadcastReceiver;连接到地理定位服务和传感器;从 ViewModel 或 Room 更新数据。在此处还通过 bindService() 进行与 Bound 服务的绑定(如果应用程序在进程内使用客户端-服务器架构)。
override fun onStart() {
super.onStart()
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
5000L,
10f,
locationListener
)
}
override fun onStop() {
super.onStop()
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.removeUpdates(locationListener)
}
重要规则:在 onStart 中连接的资源必须在 onStop 中释放。这确保当 Activity 在屏幕上不可见时,不会消耗电池和系统资源。Google Play Store 在审核更新时会检查应用程序是否存在 LocationListener 和其他系统服务的泄漏。
onResume() — Activity 位于前台并准备好与用户交互的状态。这是屏幕的工作状态:系统将输入焦点交给 Activity,所有触摸事件、键盘输入和手势都定向到此屏幕。onResume 方法在 Activity 每次返回前台时调用 — 在另一个 Activity 完成后、在关闭对话框后、在解锁设备后。
在 onResume 中执行:恢复在 onPause 中暂停的动画;打开相机和其他独占资源;注册传感器监听器(加速度计、陀螺仪);为 UI 启动计时器和秒表;用最新数据更新屏幕内容。在 onResume / onPause 对中处理仅在焦点时应激活的资源 — 例如连续语音识别或视频捕获。
override fun onResume() {
super.onResume()
cameraHolder.openCamera()
animator.resume()
sensorManager.registerListener(
stepCounter,
sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
SensorManager.SENSOR_DELAY_NORMAL
)
}
override fun onPause() {
super.onPause()
cameraHolder.closeCamera()
animator.pause()
sensorManager.unregisterListener(stepCounter)
}
onStart 和 onResume 之间的区别很重要:Activity 可能可见(onStart)但不活动(onResume)— 例如,当在其上方显示弹出对话框或透明锁定屏幕时。正是在 onResume 中,而不是在 onStart 中,应该打开需要独占访问的独占资源。
当 Activity 失去输入焦点但仍部分可见时调用 onPause()。典型场景:打开对话框、按下「最近应用」按钮、来电、按下「主页」按钮(在这种情况下 onPause 之后会调用 onStop)。onPause 方法是保存用户不应丢失的数据的最后一个可靠位置。
在 onPause 中执行:将电子邮件草稿和输入表单保存到 Room 或 SharedPreferences;停止动画和视频播放;关闭相机并释放独占资源;取消对后台不关键的高成本操作。onPause 方法必须在 不到 100 毫秒 内完成 — 系统会阻塞到下一个 Activity 的转换,直到 onPause 返回控制权,超过限制会导致 ANR(应用无响应)。
override fun onPause() {
super.onPause()
val editor = SharedPreferences.Manager ...
editor.putString("draft_text", draftEditText.text.toString())
editor.apply()
videoView.pause()
cameraHolder.release()
}
重要:onPause 在 UI 线程中执行,因此所有阻塞操作(例如通过 Room 使用同步查询写入数据库)必须替换为异步操作(协程)或在后台线程中执行。对于 SharedPreferences 使用 apply() 而不是 commit() — apply 异步写入数据并且不会阻塞 UI 线程。
当 Activity 不再对用户可见时调用 onStop()。这发生在以下情况:Activity 被另一个 Activity 完全覆盖;用户按下了「主页」按钮或切换到另一个应用程序;Activity 正在结束(然后会调用 onDestroy)。在 onStop 状态下,Activity 保留在内存中并保留其所有字段 — 既未被销毁,也不活动。
在 onStop 中执行:退订在 onStart 中注册的 BroadcastReceiver;断开与 Bound 服务的连接;释放 LocationListener、SensorListener 和其他系统监听器;停止应用程序隐藏时不需要的长时间后台操作;通过 onSaveInstanceState() 将当前 UI 状态写入 Bundle(如果这未在 onPause 中完成)。
override fun onStop() {
super.onStop()
unregisterReceiver(connectivityReceiver)
unbindService(serviceConnection)
if (isChangingConfigurations()) {
Log.d("Lifecycle", "Activity 因配置更改而重新创建")
}
}
在内存不足时,系统可以在不调用 onDestroy 的情况下销毁 onStop 状态下的 Activity。因此,所有关键数据必须在转换到 onStop 之前保存。isChangingConfigurations() 标志允许确定 onStop 调用是否与屏幕旋转有关 — 在这种情况下 Activity 将被重新创建,而不是被结束。
onDestroy() — 生命周期中的最后一个方法,在完全销毁 Activity 之前调用。系统在两种情况下调用 onDestroy:Activity 通过调用 finish() 结束或用户按下「返回」按钮;Activity 因配置更改(例如屏幕旋转)被系统销毁并将重新创建。onDestroy 方法允许进行最终资源清理:分离线程和协程,关闭永久打开的游标和套接字,通过 NDK 释放本机内存。
override fun onDestroy() {
super.onDestroy()
backgroundJob.cancel()
dbHelper.close()
if (isFinishing) {
Log.d("Lifecycle", "Activity 最终结束")
} else {
Log.d("Lifecycle", "Activity 将被重新创建")
}
}
重要说明:如果应用程序进程被系统杀死(内存不足),onDestroy 不被保证。因此不能依赖 onDestroy 来保存数据 — 此任务在 onPause 或 onStop 中解决。isFinishing 属性允许区分通过 finish() 结束 Activity 和配置更改时的重新创建。
onRestart() 在 onStart() 之前调用,当 Activity 从停止状态(onStop)返回到前台时。当用户从「最近」菜单重新打开应用程序或通过在子屏幕上按「返回」按钮返回到 Activity 时,会发生这种情况。onRestart 方法允许执行与 onCreate 不同的逻辑 — 例如更新在 Activity 隐藏期间可能已更改的数据。
override fun onRestart() {
super.onRestart()
refreshDataFromNetwork()
Log.d("Lifecycle", "Activity 从堆栈重新启动")
}
典型场景:用户打开了应用程序,切换到另一个任务,一小时后返回。在 onRestart 中,应用程序可以检查数据的新鲜度,如果时间已经过去很久,建议重新加载内容。这改善了用户体验并降低了显示过时信息的可能性。
屏幕旋转 — 重新创建 Activity 的最常见场景。默认情况下,Android 在每次方向更改时销毁当前 Activity 并创建一个新的 Activity。如果不保存状态,用户将丢失所有输入的数据。为此,Android 提供了两种机制:onSaveInstanceState() 用于可序列化的数据,ViewModel 用于在配置更改后存活的数据。
onSaveInstanceState() 在销毁 Activity 之前调用以保存临时状态。保存的数据通过 savedInstanceState 参数传递给 onCreate 和 onRestoreInstanceState() 方法(后者在 onStart 之后调用)。Bundle 有大小限制 — 约 500 KB,因此大数据量(例如位图)通过 ViewModel 保存。
<!-- AndroidManifest.xml — 固定方向 -->
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize" />
通过 android:configChanges 固定方向可以防止重新创建 Activity,但如果应用程序需要支持两个方向,这被认为是反模式。Google 的现代建议 — 对用户在 UI 中输入的数据使用 ViewModel 与 onSaveInstanceState 组合。
Fragment 有自己的生命周期,类似于 Activity,但有额外的方法:onAttach、onCreate、onCreateView、onViewCreated、onStart、onResume、onPause、onStop、onDestroyView、onDestroy、onDetach。Fragment 始终存在于 Activity 内部,其生命周期与容器 Activity 的生命周期绑定。如果 Activity 被销毁,Fragment 也随之销毁。
主要区别:Fragment 不仅管理组件的状态,还管理 View 层次结构。onCreateView 方法返回 fragment 的根 View,onDestroyView 销毁此层次结构。这允许 Fragment 在屏幕旋转时存活于 Activity 的重新创建:Fragment 被保留,其 View 在 onCreateView 中重新创建。
class ProfileFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.fragment_profile, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val avatarImage: ImageView = view.findViewById(R.id.avatar_image)
loadAvatar(avatarImage)
}
}
理解 onCreate 和 onCreateView 之间的区别至关重要:onCreate 在 Fragment 的生命周期中调用一次(即使在 View 重新创建时),而 onCreateView 在 Fragment 创建或重新创建其 View 层次结构时每次调用。数据初始化在 onCreate 中完成,UI 绑定在 onViewCreated 中完成。
LifecycleObserver — Android Jetpack 库的组件,允许在不必重写 Activity 或 Fragment 中的方法的情况下响应生命周期变化。与其在每个生命周期方法中重复代码,开发者创建一个带有 @OnLifecycleEvent 注解的独立类并将其传递给 lifecycle.addObserver()。
Jetpack 还提供了 LifecycleOwner 类 — 由 AppCompatActivity 和 Fragment 实现的接口。任何实现 LifecycleOwner 的对象都可以管理与生命周期相关的 LiveData 订阅、通过 lifecycleScope 的协程以及 WorkManager 的工作。这是基于 MVVM 和 Jetpack 的现代 Android 架构的基石。
class MyLocationObserver(private val context: Context) : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
startLocationUpdates()
}
override fun onStop(owner: LifecycleOwner) {
stopLocationUpdates()
}
}
// 在 Activity 中:
lifecycle.addObserver(MyLocationObserver(this))
使用 DefaultLifecycleObserver 简化了测试,减少了代码重复,并使生命周期逻辑在不同屏幕之间可重用。这是每个 Activity 中手动重写 onStart/onStop 的现代替代方案。在 IT Sectr 开发的 Android 应用程序中,我们将 LifecycleObserver 用于地理定位、蓝牙扫描和分析 — 这可将样板代码量减少 30-40%。
常见问题
如果不调用 super.onCreate() 或任何其他生命周期 super 方法,系统将抛出 SuperNotCalledException 异常,应用程序将崩溃。这是 Android Runtime 的硬性要求 — 每个方法必须将执行委托给基类,否则内部有限状态机无法转换到下一个状态。
Activity 在屏幕旋转时会重新创建,因为 方向更改是设备配置更改(configuration change)。默认情况下,Android 销毁 Activity 并创建一个新的 Activity 以加载替代资源(layout-land、values-land)。要禁用重新创建,可以在清单中添加 android:configChanges 属性,但 Google 建议使用 ViewModel 来保存数据。
关键数据在 onPause() 中保存,因为这是应用程序被系统杀死之前保证会调用的最后一个方法。在 onStop 和 onDestroy 之后,系统可以在不调用额外方法的情况下结束进程。对于草稿和临时数据,使用具有 apply() 的 SharedPreferences 或具有协程的 Room。
onPause 在 Activity 失去焦点但仍部分可见时调用(例如,打开了对话框)。onStop 在 Activity 被其他 Activity 或通过按「主页」按钮完全从屏幕隐藏时调用。主要实际区别:onPause 是数据保存的最后一个点,onStop 是释放后台不需要的监听器和系统服务的地方。
ViewModel — Android Jetpack 的组件,用于存储 UI 数据并自动在配置更改(屏幕旋转)后存活。ViewModel 在 Activity 重新创建时不会被销毁:它一直存在,直到 LifecycleOwner(Activity 或 Fragment)最终结束。这解决了在屏幕旋转时无需使用 Bundle 和 onSaveInstanceState 保存数据的问题。ViewModel 是 Google 推荐的 MVVM 架构的强制元素。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。