Android Activity生命周期详解与最佳实践
1. Activity生命周期概述在Android开发中Activity作为应用的核心组件其生命周期管理是每个开发者必须掌握的基础知识。Activity生命周期指的是一个Activity从创建到销毁的完整过程以及在这个过程中可能经历的各种状态变化。1.1 为什么需要理解生命周期想象一下你正在使用一个视频播放应用当接到电话时视频会自动暂停挂断电话后视频又能从暂停处继续播放旋转手机时界面能自动适应新的屏幕方向切换到其他应用再返回时进度不会丢失这些流畅的用户体验背后正是Activity生命周期管理的功劳。如果处理不当可能会出现意外崩溃资源浪费如后台继续播放音频用户数据丢失电池快速耗尽等问题1.2 生命周期状态与回调方法Activity主要有以下几种状态已创建Created已启动Started已恢复Resumed已暂停Paused已停止Stopped已销毁Destroyed每个状态转换时系统都会调用对应的回调方法开发者可以在这些方法中执行适当的操作。这些回调方法共同构成了Activity的生命周期流程图。2. 核心生命周期方法详解2.1 onCreate() - 初始化之地override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化UI组件 val textView findViewByIdTextView(R.id.text_view) // 恢复保存的状态 savedInstanceState?.let { textView.text it.getString(text_content) } // 初始化ViewModel viewModel ViewModelProvider(this).get(MainViewModel::class.java) }关键点必须调用super.onCreate()通常在这里执行一次性初始化操作savedInstanceState用于恢复被系统销毁前的状态避免在这里执行耗时操作否则会影响启动速度常见错误忘记调用父类方法在setContentView之前访问视图执行网络请求等阻塞UI的操作2.2 onStart() - 准备亮相override fun onStart() { super.onStart() // 注册广播接收器 registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) // 启动位置更新 locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_MS, MIN_DISTANCE_M, locationListener ) }适用场景注册系统广播启动位置监听初始化需要在界面可见时运行的组件注意事项与onCreate不同onStart可能被多次调用确保与onStop配对使用避免资源泄漏2.3 onResume() - 前台焦点override fun onResume() { super.onResume() // 恢复动画 animationView.resumeAnimation() // 获取相机权限后重新打开相机 if (hasCameraPermission()) { openCamera() } // 更新UI数据 updateUserProfile() }典型用途恢复暂停的动画重新初始化传感器刷新可能过时的数据获取独占资源如相机重要特性Activity在此状态时位于栈顶并与用户交互可能频繁进出此状态如来电、权限对话框2.4 onPause() - 暂停处理override fun onPause() { // 暂停正在进行的操作 mediaPlayer.pause() // 释放独占资源 releaseCamera() // 保存临时数据 preferences.edit().putInt(last_position, currentPosition).apply() super.onPause() }最佳实践必须快速执行系统会等待方法完成适合保存简单数据到SharedPreferences不适合执行耗时操作如数据库写入注意调用super.onPause()的顺序通常最后调用2.5 onStop() - 后台处理override fun onStop() { // 取消网络请求 requestJob?.cancel() // 注销广播接收器 unregisterReceiver(batteryReceiver) // 保存数据到数据库 viewModel.saveUserData() super.onStop() }与onPause的区别Activity完全不可见时调用适合执行相对耗时的保存操作在多窗口模式下可能不会调用2.6 onDestroy() - 最终清理override fun onDestroy() { // 释放资源 mediaPlayer.release() sensorManager.unregisterListener(this) // 清理Handler防止内存泄漏 handler.removeCallbacksAndMessages(null) super.onDestroy() }调用场景用户主动退出按返回键调用finish()配置变更如旋转屏幕系统回收资源注意不能依赖此方法保存数据因为可能不会被调用3. 状态保存与恢复3.1 处理配置变更当屏幕旋转等配置变更发生时Activity会被销毁并重建。保存状态的两种方式使用ViewModel存储界面相关数据class MainViewModel : ViewModel() { val userInput MutableLiveDataString() }使用onSaveInstanceState保存简单数据override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString(edit_text, editText.text.toString()) }3.2 恢复UI状态的最佳实践override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 使用保存的状态恢复UI val restoredText savedInstanceState?.getString(edit_text) ?: editText.setText(restoredText) // 结合ViewModel viewModel.userInput.observe(this) { text - editText.setText(text) } }推荐方案简单数据Bundle复杂数据ViewModel 持久化存储列表位置RecyclerView自带恢复机制4. 多窗口模式下的生命周期Android 7.0引入的多窗口模式带来了新的生命周期挑战4.1 分屏模式下的行为两个Activity都处于已启动但只有一个是已恢复状态焦点切换时会频繁调用onPause/onResume4.2 画中画模式视频应用override fun onPictureInPictureModeChanged(isInPiP: Boolean) { if (isInPiP) { // 进入画中画时简化UI controlsView.visibility View.GONE } else { // 恢复正常模式 controlsView.visibility View.VISIBLE } }适配建议在onStop中释放资源要更谨慎使用isChangingConfigurations区分配置变更和正常退出测试各种窗口尺寸下的表现5. 常见问题与解决方案5.1 生命周期相关崩溃问题1在onDestroy中访问已经为null的View解决方案// 错误方式 override fun onDestroy() { textView.text Goodbye // 可能崩溃 super.onDestroy() } // 正确方式 override fun onDestroy() { if (!isChangingConfigurations) { // 仅在实际退出时执行 saveData() } super.onDestroy() }问题2异步回调导致的内存泄漏解决方案// 使用lifecycleScope自动取消协程 lifecycleScope.launch { // 网络请求代码 } // 或者手动管理 private val job Job() override fun onCreate() { viewModel.data.observe(this) { data - // 更新UI } } override fun onDestroy() { job.cancel() super.onDestroy() }5.2 生命周期感知组件使用LifecycleObserver简化生命周期管理class MyLocationListener(private val lifecycle: Lifecycle) : LifecycleObserver { OnLifecycleEvent(Lifecycle.Event.ON_START) fun start() { // 开始监听位置 } OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun stop() { // 停止监听位置 } } // 在Activity中使用 val listener MyLocationListener(lifecycle) lifecycle.addObserver(listener)5.3 测试生命周期使用AndroidX Test测试生命周期行为RunWith(AndroidJUnit4::class) class MainActivityTest { Test fun testLifecycle() { val scenario launchActivityMainActivity() // 模拟生命周期变化 scenario.moveToState(Lifecycle.State.CREATED) scenario.moveToState(Lifecycle.State.STARTED) scenario.moveToState(Lifecycle.State.RESUMED) // 验证状态 // ... scenario.close() } }6. 现代Android开发的最佳实践随着Jetpack组件和Compose的普及生命周期管理有了新的模式6.1 使用ViewModel保存数据class MainViewModel : ViewModel() { private val _data MutableLiveDataString() val data: LiveDataString _data fun loadData() { viewModelScope.launch { _data.value repository.fetchData() } } }6.2 在Compose中处理生命周期Composable fun MyScreen(viewModel: MainViewModel) { val data by viewModel.data.observeAsState() // 自动处理生命周期的效果 LaunchedEffect(Unit) { viewModel.loadData() } // UI内容 Text(text data ?: Loading...) }6.3 使用Flow替代LiveDataclass MainViewModel : ViewModel() { val data: FlowString repository.dataFlow init { viewModelScope.launch { repository.startFetching() } } } // 在Activity中收集 lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.data.collect { data - updateUI(data) } } }掌握Activity生命周期是Android开发的基础但随着架构组件的演进我们有了更多工具来简化生命周期管理。关键在于理解原理根据应用场景选择合适的方法并通过充分测试确保各种场景下的稳定表现。

相关新闻

OpenClaw:本地化AI助手的革命性架构与应用

OpenClaw:本地化AI助手的革命性架构与应用

1. OpenClaw:重新定义个人AI助手的边界第一次在Telegram里收到OpenClaw自动整理的会议纪要时,我盯着手机屏幕足足愣了三分钟。这个自称"小龙虾"的AI不仅准确识别了Zoom会议录音中的关键决策点,还根据历史对话自动关联了待办事项&am…

2026/10/18 3:59:36 阅读更多 →
响应json数据和文本数据

响应json数据和文本数据

响应页面 响应数据 文本数据 json数据 package com.ycl.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; Controller public class UserController {RequestMapping("/toJumpPage")…

2026/10/18 3:59:39 阅读更多 →
Vue双向绑定原理与实战:从v-model到defineModel

Vue双向绑定原理与实战:从v-model到defineModel

1. 初识Vue双向绑定:从原生表单到组件通信第一次接触Vue的双向绑定是在2016年接手一个后台管理系统重构项目时。当时团队从jQuery转向Vue,最让我震撼的就是v-model这个魔法般的指令——它用一行代码就解决了表单数据和状态的同步问题。但真正深入使用后才…

2026/10/18 4:01:16 阅读更多 →

最新新闻

Aspen Plus Skill自动化更新系统设计与实现

Aspen Plus Skill自动化更新系统设计与实现

1. 项目概述:当流程模拟工程师开始写“自动更新脚本”你有没有过这样的经历:凌晨两点,盯着Aspen Plus界面里那个灰掉的“Update Skill”按钮发呆?刚改完一个热力学模型参数,想顺手把配套的Skill脚本同步更新到最新版&a…

2026/10/18 13:28:00 阅读更多 →
Java地理位置定位系统:NMEA解析、GeoHash+RTree空间索引与离线围栏判定

Java地理位置定位系统:NMEA解析、GeoHash+RTree空间索引与离线围栏判定

简介:这是一份面向高校计算机专业本科生的Java课程设计实践资源,聚焦地理位置定位功能开发,帮助学习者掌握Java GUI、数据库交互与GIS地图集成等综合技能。资源包含73个文件,主体为15个Java源码(含核心业务逻辑与Swing…

2026/10/18 13:28:00 阅读更多 →
多种小游戏合集开发复盘:架构、玩法与优化实践

多种小游戏合集开发复盘:架构、玩法与优化实践

最近我把手头零散写了很久的多个休闲小游戏统一收拢成了一个合集项目,项目标题就叫“多种小游戏”。起因很朴素:时间碎片化的玩家希望一个页面里能随时换着玩,我自己也想借这个机会把以前东一榔头西一棒子写的小游戏代码从逻辑到交互梳理清楚…

2026/10/18 13:28:00 阅读更多 →
Python自动化生成深度学习课件PPT:可复现的工程化实践

Python自动化生成深度学习课件PPT:可复现的工程化实践

简介:这是一份面向深度学习初学者与进阶学员的Python课件PPT,系统梳理从编程基础到主流模型再到行业落地的完整知识链路,帮助读者建立理论认知并衔接工程实践。内容覆盖Python语法与流程控制、数据清洗与标准化、线性回归、神经网络结构与激活…

2026/10/18 13:28:00 阅读更多 →
深度学习入门:从课件PPT到NumPy手写神经网络与PyTorch实战

深度学习入门:从课件PPT到NumPy手写神经网络与PyTorch实战

简介:这份《深度学习原理与应用》课件PPT面向高校学生、自学者及希望系统入门人工智能的开发者,帮助其建立从数学基础到经典模型的完整知识框架。课件共十一章,从深度学习概述讲起,依次覆盖线性代数、概率论与统计学、微积分与优化…

2026/10/18 13:28:00 阅读更多 →
Linux下NVML初始化失败:驱动与库版本不匹配的排查与修复指南

Linux下NVML初始化失败:驱动与库版本不匹配的排查与修复指南

1. 这个报错到底在说什么Failed to initialize NVML: Driver/library version mismatch这行字,但凡在 Linux 上跑过深度学习训练、折腾过显卡直通、或者手贱升级过一次系统内核的人,大概率都见过。它的字面意思很直白:NVML 初始化失败&#x…

2026/10/18 13:26:59 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →