- 文档
- 教程
- 知识库
【免费下载链接】developer-roadmap
Interactive roadmaps, guides and other educational content to help developers grow in their careers.
Activity 生命周期是 Android 应用开发中每个开发者都必须掌握的核心知识:它定义了一个 Activity 从创建到销毁所经历的状态集合与回调序列。本文以 developer-roadmap 仓库 Android 学习路线 中的 Activity 生命周期专题为核心,系统讲解六大回调的执行时机与正确用法,并结合电话打断、屏幕旋转等真实场景,给出状态保存与恢复的完整实战方案。读完本文,你将能正确处理配置变更、避免数据丢失,并写出可预测、稳定的 Android 界面代码。
Activity 生命周期是什么
在 Android 中,Activity 代表应用中的一个带用户界面的独立屏幕(参见 Activity 专题)。与普通 Java 对象不同,Activity 的生命周期由操作系统全权管理:用户操作、系统事件(如来电、锁屏)都会触发状态的切换,而系统可能在任意时刻销毁 Activity 以回收内存。
Activity 生命周期就是一系列状态与回调的集合,从创建到销毁依次经历。正确处理这些回调,是保证应用在电话打断、屏幕旋转等场景下不丢失数据的前提。
六大核心回调逐个拆解
生命周期中最关键的六个回调分别是:onCreate、onStart、onResume、onPause、onStop、onDestroy。下面逐一说明它们的触发时机与典型用途。
onCreate:一次性的初始化
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化 UI、绑定数据、创建对象 }- 时机:Activity 被创建时触发,是整个生命周期的起点。
- 特点:Activity 整个生命周期内只会执行一次(不计算进程被系统杀死后的重建)。
- 典型用途:
setContentView加载布局、初始化成员变量、绑定 View 事件、创建 ViewModel 等。 - 参数
savedInstanceState:若 Activity 因配置变更(如屏幕旋转)被重建,该 Bundle 中包含上一次保存的状态数据;首次创建时它为null。这是状态恢复的入口,详见下文“状态保存与恢复”。
onStart:界面即将可见
override fun onStart() { super.onStart() // 启动需要界面可见才运行的工作,如动画、位置更新 }- 时机:Activity 即将对用户可见时触发(可能还处于后台、被遮挡状态)。
- 特点:可被多次调用。Activity 从后台返回前台时会再次经过
onStart。 - 典型用途:启动仅需“可见”级别的资源占用,如开始播放动画、注册广播接收器等。
onResume:获得焦点,可交互
override fun onResume() { super.onResume() // 恢复被暂停的工作,如相机预览、传感器监听 }- 时机:Activity 到达前台顶部、可接收用户输入时触发。
- 特点:生命周期中最“活跃”的状态。任何弹窗、分屏或来电打断都会让 Activity 先经历
onPause,回来后重新走onResume。 - 典型用途:恢复暂停的动画/计时器、申请传感器监听、刷新需要“前台焦点”的数据。
onPause:部分可见,即将失去焦点
override fun onPause() { super.onPause() // 暂停重负载操作:停止动画、释放独占资源 }- 时机:Activity 部分可见但已失去输入焦点时触发,例如弹出对话框、来电、用户按下 Home 键。
- 特点:
onPause执行后,Activity 仍可能处于可见状态(如被半透明对话框遮挡),但不再接收用户输入。 - 重要限制:
onPause中不应执行耗时操作,也不宜在此做持久化——因为系统可能在这个回调返回后立刻杀掉进程。 - 典型用途:停止消耗 CPU 的动画、释放相机等独占硬件资源。
onStop:完全不可见
override fun onStop() { super.onStop() // 释放可见时才需要的资源,停止位置更新 }- 时机:Activity 完全不可见时触发,如进入后台、被新 Activity 完全覆盖。
- 特点:
onStop之后 Activity 仍驻留内存,返回前台时会重新走onStart→onResume。 - 典型用途:停止网络轮询、GPS 位置更新、UI 相关的动画等仅在可见时才有意义的工作。
onDestroy:销毁与收尾
override fun onDestroy() { super.onDestroy() // 释放资源、解绑监听器、清理临时对象 }- 时机:Activity 即将被销毁时触发,是整个生命周期的终点。
- 两种触发原因:
- 正常结束:用户按返回键退出,或代码调用
finish(); - 系统回收:配置变更(如屏幕旋转)导致系统销毁并重建 Activity,或系统因内存压力回收后台 Activity。
- 正常结束:用户按返回键退出,或代码调用
- 典型用途:释放未被自动管理的资源、解绑服务、注销广播接收器。注意:系统杀死进程的场景不会调用
onDestroy,所以不能依赖它做关键数据持久化。
生命周期状态流转图:看懂系统如何切换
Activity 在生命周期中游走于以下主要状态之间,触发条件各不相同:
| 状态 | 触发条件 | 界面表现 | 是否可交互 |
|---|---|---|---|
| Created(已创建) | onCreate完成 | 尚未显示 | 否 |
| Started(已启动) | onStart完成 | 可见但可能被遮挡 | 否 |
| Resumed(已恢复) | onResume完成 | 前台顶部、完全可见 | 是 |
| Paused(已暂停) | onPause完成 | 部分可见 | 否 |
| Stopped(已停止) | onStop完成 | 完全不可见 | 否 |
| Destroyed(已销毁) | onDestroy完成 | 不存在 | 否 |
完整的回调路径:
- 全新启动:
onCreate→onStart→onResume - 离开前台但未销毁(Home 键/来电):
onPause→onStop - 返回前台:
onStart→onResume - 被新 Activity 完全覆盖:
onPause→onStop;退出该 Activity 后:onRestart→onStart→onResume - 配置变更(屏幕旋转):
onPause→onStop→onDestroy→onCreate→onStart→onResume(销毁重建) - 按返回键退出:
onPause→onStop→onDestroy
理解这张流转表,是排查“数据丢失”“界面闪烁”“资源泄漏”三类问题的基础。状态变更正是由用户动作或系统事件触发的——按下 Home 键、旋转设备、接听电话都会让 Activity 在状态间切换(参见 State Changes 专题)。
状态保存与恢复:应对屏幕旋转与进程回收
状态变更章节明确指出:开发者必须在这些状态切换过程中保存并恢复 UI 状态,以防数据丢失。Android 提供两层机制:
第一层:onSaveInstanceState / onRestoreInstanceState
// 保存:在 Activity 可能被销毁前回调 override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString("user_input", editText.text.toString()) outState.putInt("selected_index", listView.selectedItemPosition) } // 恢复方式一:在 onCreate 中读取(重建时 savedInstanceState 非 null) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState != null) { val saved = savedInstanceState.getString("user_input") // 恢复 UI } } // 恢复方式二:单独的 onRestoreInstanceState(在 onStart 之后回调) override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) // 恢复需要在上文就绪后才能操作的数据 }onSaveInstanceState在 Activity可能被销毁前调用(不保证一定销毁),适合保存轻量、可序列化的瞬时 UI 状态。- 系统为
EditText、ListView等自带id的视图自动保存状态,所以自定义 View 务必设置android:id,否则状态会丢失。 onSaveInstanceState不适用于保存大量数据或对象引用——请把重量级数据交给 ViewModel 或持久化存储。
第二层:ViewModel——跨配置变更的数据载体
仅靠 Bundle 只能保存可序列化的轻量状态。对于复杂数据,正确做法是交给ViewModel:ViewModel 持有的状态在屏幕旋转等配置变更后依然存活,Activity 重建后直接复用,避免重新请求网络或重新构建数据(参见 ViewModel State 专题)。
class MainViewModel : ViewModel() { var userData: MutableLiveData<User> = MutableLiveData() // 数据在此存活,Activity 重建不丢失 }class MainActivity : AppCompatActivity() { private val viewModel: MainViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 直接复用已有 ViewModel,无需重新加载数据 viewModel.userData.observe(this) { user -> /* 更新 UI */ } } }ViewModel 的宿主(Activity 的 ViewModelStore)在配置变更时被保留,Activity 销毁(非 finishing)时不会清空;只有当 Activity 真正finish()时,ViewModel 才会随之清理。这一机制与 Room 数据库、SharedPreferences 等持久化方案配合使用,就能同时覆盖“瞬时状态”与“长期数据”两层诉求。
三层数据保存策略总结
| 数据类型 | 推荐方案 | 适用场景 |
|---|---|---|
| 瞬时 UI 状态(输入框内容、滚动位置) | onSaveInstanceState+ Bundle | 配置变更、进程回收 |
| 界面级业务数据 | ViewModel | 配置变更时复用,避免重复请求 |
| 需要跨会话保留的数据 | SharedPreferences / Room / DataStore | 应用被杀、重启后仍需存在 |
生命周期在常见场景中的完整表现
场景一:接听电话
- 来电 →
onPause(Activity 失去焦点但可能仍可见)→onStop(被来电界面完全覆盖) - 挂断电话返回 →
onRestart→onStart→onResume - 若在
onPause/onStop中暂停了动画、定位、网络轮询,这里必须恢复
场景二:屏幕旋转(配置变更)
- 旋转 →
onPause→onStop→onDestroy(Activity 被销毁) - 系统自动重建 →
onCreate(此时savedInstanceState非空,可恢复状态)→onStart→onResume - 若使用 ViewModel,数据无需重建,直接继续使用
场景三:按返回键退出
onPause→onStop→onDestroy,随后 Activity 从返回栈(Back Stack)中弹出(参见 Tasks & Backstack 专题)。注意isFinishing为 true,此时不应把临时状态写回持久层。
生命周期陷阱与最佳实践
常见陷阱
- 在 onPause 中做持久化:
onPause返回后进程可能立刻被杀,正确做法是把关键数据写入 SharedPreferences / Room / DataStore(SharedPreferences 专题)。 - 在 onStop/onDestroy 中遗漏资源释放:未解绑的广播接收器、未释放的传感器/相机是内存泄漏的常见来源。
- 不处理 savedInstanceState:旋转屏幕后输入框内容、列表滚动位置全部丢失。
- 把重逻辑塞进 onDestroy:进程被系统杀死时根本不会调用
onDestroy,依赖它保存数据必然失败。 - 忽略 Fragment 的嵌套生命周期:Fragment 拥有自己的生命周期且必须由宿主 Activity 或另一个 Fragment 托管(Fragments 专题),两者状态切换需保持一致。
最佳实践清单
- 每个回调只做该状态必需的、最小化的工作;
- 用 ViewModel 承载业务数据,用
onSaveInstanceState承载瞬时 UI 状态; - 在
onStart/onStop中配对注册/解绑可见性相关的监听器; - 在
onResume/onPause中配对申请/释放前台焦点所需的资源; - 使用
lifecycleScope、LifecycleObserver等 Jetpack 工具让组件自动感知生命周期,减少手动管理错误。
小结
Activity 生命周期是 Android 开发的基石:onCreate完成一次性初始化,onStart/onResume逐步进入可交互状态,onPause/onStop应对打断与退后台,onDestroy完成收尾。正确理解这六个回调的触发时机,配合onSaveInstanceState与 ViewModel 双通道状态保存机制,即可从容应对电话、旋转、进程回收等一切系统事件,构建稳定、不丢数据的应用。在 developer-roadmap 的 Android 学习路线 中,生命周期专题与 Activity、State Changes、ViewModel State、Tasks & Backstack 等章节共同构成 Android 界面编程的核心知识链,建议按此顺序系统学习。
- 文档
- 教程
- 知识库
【免费下载链接】developer-roadmap
Interactive roadmaps, guides and other educational content to help developers grow in their careers.
相关推荐
Seal ViewModel生命周期:配置变更的状态保存
Seal ViewModel生命周期:配置变更的状态保存 在Android应用开发中,配置变更(如屏幕旋转、语言切换)常常导致界面重建,如何确保数据不丢失是开发
移动开发音视频ShortcutBadger的Activity生命周期:角标状态保存策略
ShortcutBadger的Activity生命周期:角标状态保存策略 角标状态在Activity生命周期中的挑战 移动应用开发中,角标(Badge)作为通知
移动开发免费跨平台终端工具 Tabby 完整指南:多标签页、SSH 密钥管理与串口调试一次配齐
免费跨平台终端工具 Tabby 完整指南:多标签页、SSH 密钥管理与串口调试一次配齐 开发者的桌面永远不嫌窗口多——直到你受够了在本地 Shell、SSH 客
桌面应用网络通信
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考