Fixed
Status Update
Comments
il...@google.com <il...@google.com>
jb...@google.com <jb...@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
jb...@google.com <jb...@google.com> #3
yea i'll take it.
ap...@google.com <ap...@google.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.
il...@google.com <il...@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()
}
}
Description
When using the new state manager released in fragment 1.3.0-alpha08, if you manually (without using the hide/show fragment transactions) set the visibility state of your view after the SpecialEffectsController has started any animations/transitions on your view, the visibility changes are ignored.
The reason this happens is because the new state manager saves the visibility state of the view in
onViewCreated()
as the final state and then restores that visibility state once the special effect completes afteronStart()
. This means that any changes made by the user to the view visibility state betweenonViewCreate()
andonStart()
are completely ignored.This becomes apparent in two particular cases:
There is a fragment that is always added, but has its visibility state updated based on some internal data (i.e. an error screen that is set to
View.INVISIBLE
when there is no error andView.VISIBLE
when there is one). If the view state changes toINVISIBLE
inonStart()
, the fragment should not be shown once the add transaction completes.A entering fragment is postponed and while it is postponed, its view visibility state is set to
View.INVISIBLE
. Even once the fragment is no longer postponed, its view should still beINVISIBLE
until the user changes it again manually.The new state manager should defer view visibility state control to the user no matter when the state is changed. Doing so would ensure that the user always has the source of truth for their Fragment's view visibility.