Fragment 生命周期与 View 生命周期 · AndroidX 源码指南
AAndroidX 源码指南
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 停止/取消。
  • _bindingonDestroyView 清空,防泄漏。
  • viewLifecycleOwner 只在 View 存在期间可用。

相关页面