ursus
10/03/2021, 5:12 PMActivity {
private val scope = MainScope()
onCreate {
scope.launch {
userDao.user
.collect {
if (it == null) {
resetBackstack()
}
}
}
}
}
SomeScreenViewModel {
private val scope = MainScope()
fun init() {
scope.launch {
userDao.user
.collect {
...
}
}
}
}
UserDao.user
emits on its io dispatcher, both activity and some screen viewmodel are driven by main threaded scope (android)
Occasionally in crashlytics I see crashes related, basically to the fact that the screen collects the emit first
Is there a way I could enforce order of collections?
(I presume if it were a replayed hot Flow, then order would be the order of subscriptions, however I presume that posting to main thread will always be race-y?)marcinmoskala
10/03/2021, 5:55 PMdelay
, even a very small one. A solid one might be to make another MutableStateFlow
where the first one emits when the first one is done. Although in this case it should be enough to just add if (it == null) return@collect
on the second one.ursus
10/03/2021, 9:51 PMDALDEI
10/04/2021, 12:54 AMursus
10/04/2021, 10:34 AMDALDEI
10/05/2021, 3:12 AMvar mefirst = -1
fun meFirst() { if( mefirst < 0 ) mefirst = 0 else println("second") }
fun meSecond( if( mefirst < 0 ) mefirst = 1 else println("second") }
If on different threads needs an AtomicInt or Mutex
To enforce order something like a semaphore can work
val sem = Semaphore(1,1)
fun meFirst() { doStuff() ; sem.release() }
fun meSecond{ sem.aquire() ; doStuff() }
So would a 'token' coroutine that is waited for say
fun meFirst() = launch( CoroutineStart.LAZY ) { doFirstStuff() }
val meFirstJob = meFirst()
fun meSecond() = launch {
meFirstJob.join()
doSecondStuff()
}
I put in LAZY for no good reason -- it would work otherwise but as above it would be guarenteed to both finish first and start first
.