Kotlin SharedFlow ViewModel излучает до подписки

Я пытаюсь использовать SharedFlow в качестве поставщика данных для фрагмента в архитектуре MVVM.

В классе Фрагмент:

          override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.data.collect { value ->
                    handleData(data)
                }
            }
        }
        viewModel.init()
    }

В классе ViewModel:

          private val _data: MutableSharedFlow<DataState> = MutableSharedFlow()
    val data: SharedFlow<DataState> = _data

    fun init() {
        ...
        //(listen for other data providers that generate data for SharedFlow)
        ...
        viewModelCoroutineScope.launch {
            val dataCollection = interactor.getDataCollection()
            dataCollection.forEach { data ->
                if (data != null) {
                    _data.emit(DataState(data = data))
                }
            }
        }
    }

Проблема в том, что в 50% случаев запускается до того, как подписчик под прицелом подключится к Flow, что приводит к потере части данных. Почему используется SharedFlow? Это связано с тем, что у ViewModel есть подписки на другие источники данных, которые могут отправлять множество экземпляров данных нерегулярным образом, все, что необходимо для сбора, поэтому StateFlow/LiveData с их «сохранением только последнего значения» не подходит для этого.

Когда я пытался закрепить viewmodel.init()для сопрограммы подписчика следующим образом:

              val job = viewLifecycleOwner.lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.data.collect { value ->
                    handleData(data)
                }
            }
        }
        viewLifecycleOwner.lifecycleScope.launch {
            job.join()
            viewModel.init()
        }

ViewModel выдает данные, но Fragment никогда их не собирает.

Как правильно гарантировать, что подписчики включены до вызова ViewModel, чтобы начать отправку данных через SharedFlow?

0 ответов

Другие вопросы по тегам