I have a lifecycle
aware fragment scope coroutine function that checks whether a value received from the fragments' parent activity has a certain value. If the value is null
a function is called that has viewModelScope.launch
coroutine scope to start a count down before showing a dialog to inform the user that the value disables certain app functionalities.
The problem is that the viewModelScope.launch
coroutine function is called all the time even though the conditional if statement is not true.
My question is why would a viewModelScope
coroutine function be called if it is inside a conditional that is clearly false? I did notice that if I Log
an output inside the if
conditional it is not logged and if I Log
output outside the viewModelScope.launch
coroutine it is also not called. So the scoped code runs notwithstanding the value of the conditional.
The workaround for this was to make the viewmodel function a suspend
function and remove the viewModelScope.launch
coroutine. But why would a function be called that does not meet a conditional. Does coroutines transcend the boundaries of logic?
The lifecycleScope
function has the following make up:
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
viewModel.status.collectLatest {
binding.contentScanner.tvScannerStatus.text = it
if (statusCheck(it) == null) {
viewModel.reactToInactiveScanner(it) // This function is called even though the condition is false
}
}
}
}
The viewModelScope
coroutine:
fun reactToInactiveScanner(s: String) {
viewModelScope.launch {
for(i in 1..5) {
if(isScannerUnavailable(s)) break
delay(1000L)
}
_scannerActive.value = isScannerUnavailable(s)
}
}
CodePudding user response:
Probably statusCheck(it)
is null when you think it is not ooor, since reactToInactiveScanner(s: String)
is launching a coroutine in the view model scope and suspending for at least 5 seconds, and given that the viewmodel survives configuration change, doesnt matter what the lifecycle is doing, the coroutine in the viewmodel scope will keep running for 5 seconds.
try to make the function suspending :
suspend fun reactToInactiveScanner(s: String) {
for(i in 1..5) {
if(isScannerUnavailable(s)) break
delay(1000L)
}
_scannerActive.value = isScannerUnavailable(s)
}
and launch it in the lifecycle scope, so when the lifecycle stop the coroutine get canncelled and when it starts the coroutine gets launched again