coroutine view model execution

103 Views Asked by At

I have a view model which holds some live data (hasExpanded), and a coroutine that are both called in onViewCreated, but the coroutine always executes first, for example :

@ExperimentalCoroutinesApi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    setActionBar()
    super.onViewCreated(view, savedInstanceState)
    observeHasExpandedState()
    viewLifecycleOwner.lifecycleScope.launch {
        Log.d("DETAIL", "launch")
        if (!hasExpanded){
            Log.d("DETAIL", "!hasExpanded")
            Log.d("DETAIL", "setImageView started")
            setImageView(imageUrl) // waits for a callback to complete
            Log.d("DETAIL", "setImageView finished")
            Log.d("DETAIL", "handleEnterAnimation started")
            handleEnterAnimation() // waits for animation to complete
            Log.d("DETAIL", "handleEnterAnimation finished")
            viewModel.setRevealAnimationExpandedState(true)
        }
        observeSomeOtherData()
    }
}



private fun observeHasExpandedState() {
    viewModel.revealAnimationExpanded.observe(
        viewLifecycleOwner,
        Observer { hasExpanded ->
            Log.d("DETAIL", "hasExpanded changed - $hasExpanded")
            this.hasExpanded = hasExpanded
        }
    )
}

From this I want D/DETAIL: hasExpanded changed - false to be printed first but the above code will print something like this

    D/DETAIL: launch
    D/DETAIL: !hasExpanded
    D/DETAIL: setImageView started
    D/DETAIL: hasExpanded changed - false # (I want to have this called first)
    D/DETAIL: setImageView started
    D/DETAIL: setImageView finished
    D/DETAIL: handleEnterAnimation started
    D/DETAIL: handleEnterAnimation finished
    D/DETAIL: hasExpanded changed - true
    D/DETAIL: observeSomeOtherData

I could fix this simply by using savedInstanceState or sharedPreference or even calling the coroutine from the view model observe method, but this code is using the new view model with saved state so don't really want to resort to any of those options, I just wonder if there's a way to make it call in the order I want it?

Also I'm guessing this is either to do with how long it takes for the view model to initialise the data, or its because I'm using viewLifecycleOwner for the view model and lifecycleScope.launch for the coroutine which is dispatchers.Main.immediate but if anyone has a definitive explanation for why this happens I'd appreciate it.

Ive tried moving the order, calling in onCreateView and onCreate to no avail

1

There are 1 best solutions below

0
On

LMAO as i posted this i changed my coroutine to use Dispatchers.Main and it worked lol