When should I collect SharedFlow events in Fragment lifecycle

3.8k views Asked by At

I thought that it is okay to collect SharedFlow data in onViewCreated. But when I replace fragment n times then I fire some event to SharedFlow, it emits n times event to me instead of one event.

To fix it I put my code in onCreate of my fragment. I couldn't find any documentation about that. Am I missing something or should I keep collecting SharedFlow in onCreate in the fragment?

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    lifecycleScope.launchWhenResumed {
        viewModel.uiEffect.collect {
            when (it) {
                is ViewEffectWrapper.PageEffect -> {
                    if (it.pageEvent is LoginViewEffect.OpenHomePage) {
                        startActivity(
                            Intent(
                                [email protected],
                                HomeActivity::class.java
                            )
                        )
                    }
                }

            }
        }
    }
}

And here is my SharedFlow definition in the ViewModel

private val _uiEffect = MutableSharedFlow<ViewEffectWrapper<LoginViewEffect>>(replay = 0)
val uiEffect: SharedFlow<ViewEffectWrapper<LoginViewEffect>> = _uiEffect
1

There are 1 answers

2
che10 On

You are not currently using the viewLifecycleOwner and it is recommended to use that for Fragments as that is tied to the Fragment Views Lifecycle. This is the recommended way to do it

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // ...
        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiEffect.collect {
                    // do stuff here
                }
            }
        }
    }

I would also like to give this a read. It is a good read and worth to help you ahead.

https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda