
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开发的基础但随着架构组件的演进我们有了更多工具来简化生命周期管理。关键在于理解原理根据应用场景选择合适的方法并通过充分测试确保各种场景下的稳定表现。