Fixed
Status Update
Comments
be...@citymapper.com <be...@citymapper.com> #2
Yigit, do you have time to fix it?
reemission of the same liveData is racy
reemission of the same liveData is racy
il...@google.com <il...@google.com> #3
yea i'll take it.
be...@citymapper.com <be...@citymapper.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()
}
}
mr...@gmail.com <mr...@gmail.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)
il...@google.com <il...@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
Version used: 1.2.0-rc03
Devices/Android versions reproduced on:
- Pixel 3 API 27 Emulator
- Pixel 3 API 29 Emulator
- LG G7 ThinQ API 28
Sample code:
How to use:
- Make sure Fragment F1 is using layout fragment_f1_bad. Use the code to start the MainActivity, produce a configuration change (eg: rotate the device) --> it will crash due to an Exception is thrown in a check code.
- Changing F1 layout to fragment_f1_good and it will be fine.
Description:
- Saying I have a Fragment F1 in my Activity, defined either by xml (fragment tag or FragmentContainerView) or manual adding at runtime.
- F1's layout is defined in an xml with a 'fragment' tag whose name is a Fragment F2.
- The app starts normally as usual.
- If a configuration change happens, the destruction of F1 will call F2's onViewCreated.
In the sample app, I put a check code which checks if the Activity is destroyed or not, and in this case it will crash the app.
The expected behavior should be: the destruction of F1 should not call F2's onViewCreated.
This issue doesn't occur on 1.2.0-rc03 IF I use `FragmentContainerView` instead of `fragment` to add F2.
This issue cannot be reproduced on 1.2.0-rc02, 1.2.0-rc01 and (I believe) earlier versions.
Please find a call stack in attached screenshot (taken from a debug session on Pixel 3 API 29 Emulator).