Fixed
Status Update
Comments
il...@google.com <il...@google.com>
il...@google.com <il...@google.com> #2
Yigit, do you have time to fix it?
reemission of the same liveData is racy
reemission of the same liveData is racy
va...@google.com <va...@google.com> #3
yea i'll take it.
il...@google.com <il...@google.com>
al...@gmail.com <al...@gmail.com> #4
Thanks for the detailed analysis. This may not be an issue anymore since we've started using Main.immediate there but I' not sure; I'll try to create a test case.
va...@google.com <va...@google.com> #5
just emitting same live data reproduces the issue.
@Test
fun raceTest() {
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData)
emitSource(subLiveData) //crashes
}
subject.addObserver().apply {
testScope.advanceUntilIdle()
}
}
@Test
fun raceTest() {
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData)
emitSource(subLiveData) //crashes
}
subject.addObserver().apply {
testScope.advanceUntilIdle()
}
}
ap...@google.com <ap...@google.com> #6
With 2.2.0-alpha04 (that use Main.immediate), the issue seems to be still there (I tested it by calling emitSource() twice, like your test case)
jb...@google.com <jb...@google.com> #7
yea sorry immediate does not fix it.
I actually have a WIP fix for it:
https://android-review.googlesource.com/c/platform/frameworks/support/+/1112186
if your case is the one i found (emitting same LiveData multiple times, as shown in #5) you can work around it by adding a dummy transformation.
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData.map {it })
emitSource(subLiveData.map {it} )
}
I actually have a WIP fix for it:
if your case is the one i found (emitting same LiveData multiple times, as shown in #5) you can work around it by adding a dummy transformation.
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData.map {it })
emitSource(subLiveData.map {it} )
}
Description
Compose provides
rememberSaveable
, along with accompanying tools likeSaver
andSaveableStateRegistry
as its mechanisms for storing saved instance state. Currently, there isn't a provided interoperability layer between these tools andSavedStateHandle
.If
SavedStateHandle
isn't used in theViewModel
, state that is hoisted from@Composable
s toViewModel
s won't be stored to saved instance state. This might either cause bugs due to state loss upon process death, or act as a barrier to hoisting state sufficiently if it seems likerememberSaveable
has to be used to remember state across process recreation.The proposal is to provide the necessary hooks for
SavedStateHandle
withSaver
so that any state holder that is being saved viarememberSaveable
could also be saved withSavedStateHandle
.