Fragment
应用基础 · androidx.fragment
Fragment 生命周期与 View 生命周期1.9.0-rc01
Fragment 存活不代表它的 View 仍然存在;viewLifecycleOwner 的正确用法。
最后更新 2026-08-01
两个生命周期
Fragment 自身生命周期长于它的 View:
Fragment: onCreate → onCreateView → onViewCreated → onStart → ... → onDestroyView → onDestroy
View: ↑(创建) ↑(销毁) ↑onCreateView 创建视图,onDestroyView 后 Fragment 仍可能留在 FragmentManager/back stack 中(比如被 hide 或处于返回栈)。
观察 UI 状态用 viewLifecycleOwner
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect(::render)
}
}
}- 观察只服务于 View 的 UI 状态 → 绑定
viewLifecycleOwner。 - View 销毁时收集自动停止,避免更新已销毁的 UI。
- Fragment 级
lifecycle只用于”Fragment 活着就要做”的事。
什么时候用哪个
| 场景 | 用 |
|---|---|
| 更新 View 内容 | viewLifecycleOwner |
| 网络/数据加载(不碰 UI) | viewLifecycleOwner 或 Fragment lifecycle(看是否需 View) |
| 注册 View 相关监听 | viewLifecycleOwner |
| Fragment 级资源(不依赖 View) | Fragment lifecycle |
原则:onViewCreated 之后的 UI 工作都用 viewLifecycleOwner,除非明确要跨 View 存活。
ViewBinding 清理
private var _binding: FragmentDetailBinding? = null
private val binding get() = _binding!!
override fun onCreateView(...): View {
_binding = FragmentDetailBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null // 必须清空,否则持有已销毁的 View 树
}不清空 → Fragment 持有已销毁的 View,内存泄漏 + 可能访问非法 View。
viewLifecycleOwner 的限制
onCreateView之前调用 → 抛异常。onDestroyView之后调用 → 抛异常。- 只有返回非 null View 的 Fragment 才有 view lifecycle。
viewLifecycleOwner的状态:View 处于CREATED后才是LIFECYCLE_OWNER可用。
复制即用
class ProfileFragment : Fragment() {
private var _binding: FragmentProfileBinding? = null
private val binding get() = _binding!!
private val viewModel: ProfileViewModel by viewModels()
override fun onCreateView(inflater, container, savedInstanceState): View {
_binding = FragmentProfileBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state -> render(state) }
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}常见陷阱
- 用 lifecycleOwner 而非 viewLifecycleOwner 观察 UI:View 销毁后继续收数据。
- _binding 不置空:
onDestroyView必须置 null,防泄漏。 - 在 viewLifecycleOwner 外使用它:它只在 View 生命周期内有效。
- onCreateView 里启动协程:用
viewLifecycleOwner.lifecycleScope而非 Fragment scope。
要点
- Fragment 生命周期长于 View;View 在
onDestroyView后可能已销毁。 - UI 观察绑定
viewLifecycleOwner,随 View 停止/取消。 _binding在onDestroyView清空,防泄漏。- viewLifecycleOwner 只在 View 存在期间可用。