Sparround

Fragment lifecycle & management

A Fragment is a reusable UI portion inside an activity. The critical property: a fragment has two lifecycles:

  • The fragment itself: onAttach → onCreate → ... → onDestroy → onDetach
  • Its view: onCreateView → onViewCreated → ... → onDestroyView

When a fragment sits on the back stack, the view is destroyed (onDestroyView) but the fragment object remains. That is why view references (binding) must be cleared in onDestroyView — or you leak memory.

Use viewLifecycleOwner for view-related observation, not the fragment's own lifecycle. Observing LiveData/Flow with the fragment's lifecycleOwner is the classic cause of stale-view bugs.

kotlin
class AccountsFragment : Fragment(R.layout.fragment_accounts) {

    private var _binding: FragmentAccountsBinding? = null
    private val binding get() = _binding!!

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        _binding = FragmentAccountsBinding.bind(view)

        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.accounts.collect { binding.list.adapter?.let { a -> (a as AccountAdapter).submitList(it) } }
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null   // leak-in qarşısını alır
    }
}

Correct ViewBinding handling and viewLifecycleOwner

Fragment-to-fragment communication is an interview classic. Modern answers: (1) a shared ViewModel (activityViewModels()), (2) the Fragment Result API (setFragmentResultListener), (3) Navigation arguments. Older approaches — interface callbacks, direct fragment references — are legacy; direct references are an antipattern.

🛠 Practice task

Build a small two-fragment flow (list → detail, with a back stack).

  • Log the fragment's and viewLifecycleOwner's lifecycles separately; navigate to detail and back — observe the difference.
  • Skip nulling the binding in onDestroyView, see what LeakCanary reports, then fix it.
  • Pass a result back with the Fragment Result API.

Done when: you can explain "why a fragment has two lifecycles" citing your own logs.

📚 Sources and documentation