Как избежать состояния гонки в FragmentManager?

Моя цель - разрешить только один экземпляр одного и того же фрагмента диалога в стеке фрагментов.

Текущее условие триггера исходит от SharedFlow и может запускаться так часто, как 7ms отдельно между значениями.

Вот что я пробовал:

  1. Размещение кода в synchronized блокировать
  2. Проверка наличия существующего фрагмента в стеке с помощью вызова fm.findFragmentByTag

Однако обоих условий недостаточно для предотвращения многократного добавления фрагмента в fragmentManager.

Я пробовал с dialogFragment.showNow(fm, tag) но он нестабилен и рушится

Благодарю за любую помощь.

      
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
  viewModel.someSharedFlow
    .flowWithLifecycle(viewLifecycleOwner.lifecycle)
    .onEach { showMyFragmentDialog() }
    .launchIn(viewLifecycleOwner.lifecycleScope)
}

private fun showMyFragmentDialog() {
  synchronized(childFragmentManager) {
    if (childFragmentManager.findFragmentByTag(MyFragment.TAG) == null) {
      MyFragment.newInstance(fuelTypes)
        .show(childFragmentManager, MyFragment.TAG)
    }
  }
}

1 ответ

Прибегал к сопрограмме на данный момент. Не идеально, но, по крайней мере, работает.

      private var myLaunchJob: Job? = null
private fun showMyFragmentDialog() {
  if (myLaunchJob?.isActive == true) return
  myLaunchJob = viewLifecycleOwner.lifecycleScope.launch {
    if (childFragmentManager.findFragmentByTag(MyFragment.TAG) == null) {
      MyFragment.newInstance(fuelTypes)
        .show(childFragmentManager, MyFragment.TAG)
    }
    // Act as debouncer
    delay(1000)
  }
}
Другие вопросы по тегам