Dilraj Singh
11/07/2022, 8:42 AMA->B
and B->C
in succession, then the composable function will only get the update of state as C
, it will never get the state B
, whereas in every other place if I collect the state flow, then I will get 2 state updates, B
and C
. Is this an intended behaviour or some bug?
Code attached in thread.Dilraj Singh
11/07/2022, 8:42 AM@HiltViewModel
class MainViewModel @Inject constructor() : ViewModel() {
private val _stateFlow = MutableStateFlow<MainState>(MainState.A)
val stateFlow = _stateFlow.asStateFlow()
init {
Log.d("debug_log", "init called for VM")
viewModelScope.launch {
_stateFlow.collect {
Log.d("debug_log", "got state in VM $it")
}
}
}
fun updateStates() = viewModelScope.launch(Dispatchers.Default) {
Log.d("debug_log", "changing state")
runCatching {
_stateFlow.update {
MainState.B
}
_stateFlow.update {
MainState.C
}
}.getOrElse {
Log.e("debug_log", "exception", it)
}
}
}
Dilraj Singh
11/07/2022, 8:42 AM@AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val mainViewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
mainViewModel.stateFlow.collect {
Log.d("debug_log", "got state in lifecycle collection $it")
}
}
setContent {
DependenciesTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
val state = mainViewModel.stateFlow.collectAsState().value
Log.d("debug_log", "got state in compose $state")
Text(text = "State is $state")
LaunchedEffect(true) {
delay(2000)
mainViewModel.updateStates()
}
}
}
}
}
}
Dilraj Singh
11/07/2022, 8:44 AMsealed class MainState {
object A : MainState()
object B : MainState()
object C : MainState()
}
Dilraj Singh
11/07/2022, 9:07 AMD/debug_log: init called for VM
D/debug_log: got state in lifecycle collection com.dependencies.MainState$A@92eabdc
D/debug_log: got state in VM com.dependencies.MainState$A@92eabdc
D/debug_log: got state in compose com.dependencies.MainState$A@92eabdc
D/debug_log: changing state
D/debug_log: got state in lifecycle collection com.dependencies.MainState$B@9359876
D/debug_log: got state in VM com.dependencies.MainState$B@9359876
D/debug_log: got state in lifecycle collection com.dependencies.MainState$C@18a0e77
D/debug_log: got state in VM com.dependencies.MainState$C@18a0e77
D/debug_log: got state in compose com.dependencies.MainState$C@18a0e77
Stylianos Gakis
11/07/2022, 5:00 PMStateFlow
. If you need in-between states then you’re not modeling state
but something else. And you may be interested in SharedFlow
instead.
StateFlow
exists to represent state, and if in a state there’s a new state overriding the old state, there’s no reason to be notified about in-between states.Pablichjenkov
11/07/2022, 5:26 PMDilraj Singh
11/07/2022, 7:10 PMDilraj Singh
11/07/2022, 7:10 PMStylianos Gakis
11/07/2022, 7:11 PMPablichjenkov
11/07/2022, 9:46 PM