Fixed
Status Update
Comments
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
kr...@gmail.com <kr...@gmail.com> #3
yea i'll take it.
jb...@google.com <jb...@google.com>
kr...@gmail.com <kr...@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.
kr...@gmail.com <kr...@gmail.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()
}
}
kr...@gmail.com <kr...@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)
th...@gmail.com <th...@gmail.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} )
}
ap...@google.com <ap...@google.com> #8
Project: platform/frameworks/support
Branch: androidx-master-dev
commit af12e75e6b4110f48e44ca121466943909de8f06
Author: Yigit Boyar <yboyar@google.com>
Date: Tue Sep 03 12:58:11 2019
Fix coroutine livedata race condition
This CL fixes a bug in liveData builder where emitting same
LiveData source twice would make it crash because the second
emission registry could possibly happen before first one is
removed as source.
We fix it by using a suspending dispose function. It does feel
a bit hacky but we cannot make DisposableHandle.dispose async
and we do not want to block there. This does not mean that there
is a problem if developer disposes it manually since our emit
functions take care of making sure it disposes (and there is
no other way to add source to the underlying MediatorLiveData)
Bug: 140249349
Test: BuildLiveDataTest#raceTest_*
Change-Id: I0b464c242a583da4669af195cf2504e2adc4de40
M lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/current.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
M lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/CoroutineLiveData.kt
M lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt
https://android-review.googlesource.com/1112186
https://goto.google.com/android-sha1/af12e75e6b4110f48e44ca121466943909de8f06
Branch: androidx-master-dev
commit af12e75e6b4110f48e44ca121466943909de8f06
Author: Yigit Boyar <yboyar@google.com>
Date: Tue Sep 03 12:58:11 2019
Fix coroutine livedata race condition
This CL fixes a bug in liveData builder where emitting same
LiveData source twice would make it crash because the second
emission registry could possibly happen before first one is
removed as source.
We fix it by using a suspending dispose function. It does feel
a bit hacky but we cannot make DisposableHandle.dispose async
and we do not want to block there. This does not mean that there
is a problem if developer disposes it manually since our emit
functions take care of making sure it disposes (and there is
no other way to add source to the underlying MediatorLiveData)
Bug: 140249349
Test: BuildLiveDataTest#raceTest_*
Change-Id: I0b464c242a583da4669af195cf2504e2adc4de40
M lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/current.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
M lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/CoroutineLiveData.kt
M lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt
ap...@google.com <ap...@google.com> #9
Project: platform/frameworks/support
Branch: androidx-main
commit 27a398bdc622236b84683d7a1c036803d77fe0d3
Author: George Mount <mount@google.com>
Date: Thu Jul 11 15:39:01 2024
Delay start of animateToStart/End() until Transition is ready.
Bug: 338624457
When a seekable transition has animateToStart() or animateToEnd()
called before the transition is ready, it was previously not
animating. Now, it waits until the transition is ready
before starting the animation.
Test: New tests, manual testing
Change-Id: I44d9618604c29659e1f6ae7e966cd1533369b18c
M transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt
M transition/transition/src/main/java/androidx/transition/Transition.java
https://android-review.googlesource.com/3168824
Branch: androidx-main
commit 27a398bdc622236b84683d7a1c036803d77fe0d3
Author: George Mount <mount@google.com>
Date: Thu Jul 11 15:39:01 2024
Delay start of animateToStart/End() until Transition is ready.
Bug: 338624457
When a seekable transition has animateToStart() or animateToEnd()
called before the transition is ready, it was previously not
animating. Now, it waits until the transition is ready
before starting the animation.
Test: New tests, manual testing
Change-Id: I44d9618604c29659e1f6ae7e966cd1533369b18c
M transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt
M transition/transition/src/main/java/androidx/transition/Transition.java
jb...@google.com <jb...@google.com> #10
This was actually an error specific to Androidx Transition, was addressed internally, and will be released in the Transition 1.5.1
version.
kr...@gmail.com <kr...@gmail.com> #11
Seems to be not fixed. My sample app is still crashing after updating to the latest libraries:
material = "1.12.0"
activity = "1.9.1"
fragment = "1.8.2"
transition = "1.5.1"
I have pushed an update to my sample library. To reproduce:
- click multiple times on "Next Fragment" (adding a fragment to the back stack)
- repeatedly perform the back gesture in a short period of time -> crash
kr...@gmail.com <kr...@gmail.com> #12
It's still crashing with the latest libraries:
material = "1.13.0-alpha05"
activity = "1.9.2"
fragment = "1.8.3"
navigation = "2.8.0"
my github repo was updated
jb...@google.com <jb...@google.com> #13
Are you seeing a new crash or is it the same trace from above? If it is a new crash can you file a separate bug with your project and the new crash?
jb...@google.com <jb...@google.com> #14
Nevermind I see
pr...@google.com <pr...@google.com> #15
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.fragment:fragment:1.8.4
pr...@google.com <pr...@google.com> #16
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.transition:transition:1.6.0-alpha01
Description
Component used: Fragment
Versions used:
Setup in Fragment:
Im getting this crash, when I navigate forward multiple times (
navigate(FragFooDirections.actionFooBar())
) and then repeatedly fast use the back gesture or back button (popBackStack()
).The same happens with a SharedAxisTransition: