Activity 生命周期
本教程共 100 篇 · 第 25 篇 · 更新于 2026-07-28 · 约 9 分钟阅读
25. Activity 生命周期
本节目标:彻底搞懂 Activity 的六个生命周期回调、什么时候触发、每个回调该干什么、状态怎么转换,理解生命周期对写健壮应用的意义。
为什么有生命周期
手机上用户随时可能离开应用:接电话、切到别的应用、按 Home 键、旋转屏幕。系统需要在这些时刻通知应用,让你保存状态、释放资源、停止动画。
Activity 生命周期就是系统给的一系列回调,告诉你「现在 Activity 处于什么状态」。在合适的回调做合适的事,应用才不会崩溃、卡顿、耗电。
六个核心回调
onCreate → onStart → onResume → [运行中] → onPause → onStop → onDestroy
↑ ↓
└──── onRestart ←──────────────┘ (回到前台)
| 回调 | 状态 | 该干什么 | 能干什么不能干什么 |
|---|---|---|---|
onCreate | 已创建 | 初始化、加载布局、绑定 ViewModel | 第一次调用,只执行一次 |
onStart | 已开始 | 注册广播、开始动画 | 可见但可能不交互 |
onResume | 已恢复 | 开始播放、恢复传感器、获取焦点 | 用户能交互,在前台 |
onPause | 已暂停 | 暂停动画、停止传感器、保存草稿 | 还部分可见,别做耗时操作 |
onStop | 已停止 | 释放重量级资源、停止网络请求 | 完全不可见 |
onDestroy | 已销毁 | 释放所有资源、解绑 | Activity 即将销毁 |
各回调详解
onCreate
Activity 创建时调用,只调一次。必须实现。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 初始化
setContentView(R.layout.activity_main) // 传统 View
// 或 setContent { ... } // Compose
viewModel = ViewModelProvider(this)[MyViewModel::class.java]
// 恢复保存的状态(第 26 章讲)
if (savedInstanceState != null) {
val score = savedInstanceState.getInt("score", 0)
}
}
savedInstanceState 是上次销毁前保存的状态 Bundle,第一次创建为 null。
onStart
Activity 即将可见时调用。从后台回到前台也会调(跟 onRestart 配合)。
适合:注册广播接收器、开始 UI 动画。
onResume
Activity 获得焦点、能跟用户交互时调用。这时 Activity 在前台。
适合:开始视频播放、恢复传感器监听、开始定位、恢复游戏循环。
override fun onResume() {
super.onResume()
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)
videoPlayer.play()
}
onPause
Activity 失去焦点、即将被另一个 Activity 部分遮挡时调用。这时 Activity 可能还部分可见(如被对话框遮住一部分)。
适合:暂停动画、停止传感器、保存草稿数据。
Warning
onPause里别做耗时操作。系统切换 Activity 时会等onPause返回,耗时会导致跳转卡顿。重活放onStop。
onStop
Activity 完全不可见时调用。可能是被新 Activity 完全覆盖,或用户按了 Home 键。
适合:停止网络请求、释放相机等重量级资源、停止播放、保存持久化数据。
override fun onStop() {
super.onStop()
sensorManager.unregisterListener(this)
videoPlayer.pause()
saveDraftToDatabase() // 保存草稿
}
onDestroy
Activity 即将销毁时调用。可能是用户 finish() 了,或系统内存不足杀了。
适合:释放所有资源、解除所有绑定、取消协程。
override fun onDestroy() {
super.onDestroy()
binding = null
coroutineScope.cancel()
}
Note
onDestroy不一定被调用。系统在极端情况下(如直接杀进程)可能跳过。所以重要数据要在onPause或onStop保存,别指望onDestroy。
完整流转场景
启动应用
onCreate → onStart → onResume
按 Home 键
onPause → onStop
应用进后台但没销毁。回到应用:
onRestart → onStart → onResume
打开新 Activity
当前 Activity:
onPause → onStop
新 Activity:onCreate → onStart → onResume
按返回回到原 Activity:
原 Activity: onRestart → onStart → onResume
新 Activity: onPause → onStop → onDestroy
旋转屏幕
onPause → onStop → onDestroy → onCreate → onStart → onResume
Activity 销毁重建。如果不处理,所有状态丢失。第 26 章讲怎么保存。
弹出对话框(半透明)
当前 Activity 只是被部分遮挡:
onPause
关闭对话框:
onResume
Tip
- 区分
onPause和onStop:部分遮挡只onPause,完全遮挡才onStop。全屏对话框走onStop,半透明走onPause。
Compose 与生命周期
Compose 项目里,生命周期感知交给 Compose 处理,别在 Activity 回调里写业务逻辑。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyAppTheme {
AppScreen()
}
}
}
}
Compose 提供生命周期感知的 API:
collectAsStateWithLifecycle():Flow 在界面可见时收集,后台时停止,省电省流量。LifecycleResumeEffect/LifecycleStartEffect:在生命周期进入 Resume/Start 时执行代码,离开时清理(Lifecycle 2.8+)。DisposableEffect:进入组合时启动,离开时清理。
@Composable
fun UserScreen(viewModel: UserViewModel) {
// 界面可见才收集 Flow,后台自动停
val state by viewModel.state.collectAsStateWithLifecycle()
DisposableEffect(Unit) {
val listener = registerSomeListener()
onDispose { listener.unregister() } // 离开组合时清理
}
}
Tip
- Compose 里 90% 的生命周期场景用
collectAsStateWithLifecycle+DisposableEffect搞定。直接操作 Activity 回调是反模式。
生命周期与进程优先级
Activity 状态影响进程优先级,决定系统杀进程的顺序:
| Activity 状态 | 进程优先级 | 被杀可能性 |
|---|---|---|
| onResume(前台) | 前台进程 | 最后杀 |
| onStart / onPause(可见) | 可见进程 | 较后杀 |
| onStop(后台) | 缓存进程 | 优先杀 |
所以后台 Activity 随时可能被系统杀。回到应用时系统会重建它(调 onCreate),你的状态保存逻辑要适应这点。
常见踩坑
在 onPause 做重活
跳转卡顿。把耗时保存移到 onStop 或异步执行。
忘记解注册
onResume 注册的广播、onStart 开始的监听,没在 onPause/onStop 解注册,会泄漏甚至重复触发。
旋转屏幕状态丢失
不处理 onSaveInstanceState,旋转后输入框、滚动位置全没了。第 26 章解决。
在 onCreate 做网络请求
onCreate 里同步做网络请求会阻塞 UI。用协程在 ViewModel 里异步做。
小结
六个回调:onCreate(初始化)、onStart(可见)、onResume(可交互)、onPause(暂停动画)、onStop(停止重活)、onDestroy(释放)。onPause 别做耗时操作,重要数据 onStop 存。Compose 项目用 collectAsStateWithLifecycle 等生命周期感知 API,别直接写回调。下一节讲状态保存。