一、生命周期联动详解
Activity状态 | Fragment状态 | 关键联动行为 |
---|---|---|
onCreate() | onAttach() → onCreate() → onCreateView() | Activity创建时初始化Fragment 在 setContentView() 后添加Fragment |
onStart() | onViewCreated() → onStart() | Fragment视图创建完成 此时可安全操作UI元素(findViewById) |
onResume() | onResume() | Fragment进入前台 启动动画/传感器等敏感操作 |
onPause() | onPause() | Fragment失去焦点 必须在此保存即时数据(如EditText内容) |
onStop() | onStop() → onDestroyView() | Fragment视图被销毁 释放Bitmap等视图相关资源 |
onRestart() | onStart() | 从后台返回时重建视图 触发onCreateView()重新创建UI |
onDestroy() | onDestroy() → onDetach() | 彻底解绑Fragment 清除对Activity的引用防止内存泄漏 |
二、核心场景分析
1. Activity启动包含Fragment
关键点:
Fragment的
onCreateView()
在Activity的onCreate()
阶段调用Fragment的
onViewCreated()
在Activity的onStart()
阶段调用UI操作安全点:在
onViewCreated()
后操作视图元素
2. 按下Home键再返回
关键点:
onStop()
后系统可能销毁Fragment视图(调用onDestroyView()
)返回时触发
onCreateView()
重建UI状态保存:使用
onSaveInstanceState()
保存数据
3. Fragment替换操作
关键点:
旧Fragment:onPause → onStop → onDestroyView
新Fragment:onAttach → onCreate → onCreateView
回退栈:
addToBackStack()
会保留旧Fragment的onDestroy之前状态
三、生命周期最佳实践
1. 初始化操作分配
操作类型 | Activity位置 | Fragment位置 | 原因 |
---|---|---|---|
视图绑定 | onCreate() | onCreateView() | 视图创建阶段 |
数据初始化 | onCreate() | onCreate() | 早于视图创建 |
监听器注册 | onStart() | onViewCreated() | 避免内存泄漏 |
动画/传感器 | onResume() | onResume() | 界面可见时启动 |
资源释放 | onStop() | onDestroyView() | 及时释放大内存对象 |
2. 状态保存与恢复
// Activity中
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("KEY", "重要数据");
}
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
String data = savedInstanceState.getString("KEY");
}
}
// Fragment中
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("FRAG_KEY", "片段数据");
}
public void onViewCreated(View view, Bundle savedInstanceState) {
if (savedInstanceState != null) {
String data = savedInstanceState.getString("FRAG_KEY");
}
}
四、总结
Q1: Activity和Fragment生命周期如何联动?
答:
创建阶段:
Activity的
onCreate()
触发Fragment的onAttach()→onCreate()→onCreateView()
Activity的
onStart()
触发Fragment的onViewCreated()→onStart()
前台交互:
Activity的
onResume()
触发Fragment的onResume()
Activity的
onPause()
触发Fragment的onPause()
后台阶段:
Activity的
onStop()
触发Fragment的onStop()→onDestroyView()
返回时Activity的
onRestart()→onStart()
触发Fragment的onCreateView()→onViewCreated()→onStart()
销毁阶段:
Activity的
onDestroy()
触发Fragment的onDestroy()→onDetach()
Q2: 按下Home键再返回会发生什么?
答:
按下Home键:
Activity:onPause() → onStop()
Fragment:onPause() → onStop() → onDestroyView()(视图被销毁)
返回应用:
Activity:onRestart() → onStart()
Fragment:onCreateView()(重建UI)→ onViewCreated() → onStart()
Activity:onResume()
Fragment:onResume()
数据恢复:
通过
onSaveInstanceState()
保存的数据在onCreateView()
的Bundle参数中恢复
Q3: Fragment的onCreate和onCreateView区别?
答:
onCreate()
:调用时机:在Fragment附加到Activity后立即调用
用途:初始化非UI组件(数据加载、ViewModel初始化)
特点:此时Fragment的视图尚未创建
onCreateView()
:调用时机:在需要绘制Fragment UI时调用
用途:创建并返回Fragment的视图层级(inflate布局)
特点:避免在此执行耗时操作(阻塞UI渲染)
Q4: 如何避免Fragment内存泄漏?
答:
视图清理:
在
onDestroyView()
中解除视图绑定:
override fun onDestroyView() { super.onDestroyView() binding = null // 使用ViewBinding时 }
监听器注销:
在
onPause()
中注销广播接收器、位置监听器等
异步任务管理:
使用
viewLifecycleOwner.lifecycleScope
启动协程在
onDestroyView()
中取消RxJava订阅
Context引用:
使用
requireContext()
替代getContext()
(自动空安全检测)
Q5: 什么时候用Fragment的onViewStateRestored?
答:
在视图状态恢复后调用(onCreateView()
之后,onStart()
之前):
典型场景:
恢复RecyclerView滚动位置
更新依赖保存状态的UI组件
优势:
此时视图层级已完全重建
保存的状态(如EditText内容)已自动恢复
使用示例:
override fun onViewStateRestored(savedInstanceState: Bundle?) { super.onViewStateRestored(savedInstanceState) savedInstanceState?.let { recyclerView.scrollToPosition(it.getInt("SCROLL_POS")) } }
重点:
强调「Fragment生命周期完全依赖宿主Activity」
记住关键顺序:Activity onStart → Fragment onViewCreated
必提视图销毁:按下Home键会触发Fragment的onDestroyView()
解决方案:ViewModel+onSaveInstanceState保存状态
安全实践:在onDestroyView()中释放所有视图资源