Status Update
Comments
jb...@google.com <jb...@google.com> #2
reemission of the same liveData is racy
dn...@google.com <dn...@google.com> #3
jb...@google.com <jb...@google.com> #4
th...@outlook.com <th...@outlook.com> #5
@Test
fun raceTest() {
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData)
emitSource(subLiveData) //crashes
}
subject.addObserver().apply {
testScope.advanceUntilIdle()
}
}
th...@outlook.com <th...@outlook.com> #6
il...@google.com <il...@google.com> #7
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} )
}
th...@outlook.com <th...@outlook.com> #8
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
jb...@google.com <jb...@google.com> #9
This leak is coming from AndroidX Transition and not Fragment. Please file an issue against that component.
th...@outlook.com <th...@outlook.com> #10
Again, neither the toolbar or the leak is the issue. These are indications that something deeper is causing issues. Please just read what I am reporting and try the sample to experience the issue yourself.
jb...@google.com <jb...@google.com>
il...@google.com <il...@google.com> #11
Thanks, we'll take another look.
jb...@google.com <jb...@google.com>
ap...@google.com <ap...@google.com> #12
Branch: androidx-main
commit 5fe62adfa9d530f4615a64d6f123a380beb61d9c
Author: Jeremy Woods <jbwoods@google.com>
Date: Wed Feb 21 22:47:46 2024
Fix issue with failing to cancel forward transitions
Prior to the Predictive back world, it was not possible to cancel any
transactions. They were atomic in nature and executing one meant that it
would finish. In the new world that is no longer the case, specifically
if you begin a forward transacation it is possible to start a predictive
back in the middle of that.
Currently, when you do this with Androidx Transitions, the view you are
seeking away from is immediately destroyed and if you do not complete
the back gesture, you are left with a blank screen.
What we should do instead is to immediately complete the forward
transaction, then begin the back gesture as if you had started from a
resumed fragment. This gets us into a known state that we can correctly
recover from.
RelNote: "Fixed an issue in Fragments where interrupting incoming
transitions with a Predictive back gesture would destroy the entering
view, potentially leaving a blank screen."
Test: Added FragmentTransitionSeekingTest
Bug: 319531491
Change-Id: Id3f228dd5f53742c68e6cb16b752022e18e00ec9
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
M transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionSeekingTest.kt
M transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionTest.kt
M transition/transition/src/main/java/androidx/transition/FragmentTransitionSupport.java
jb...@google.com <jb...@google.com> #13
This has been fixed internally and will be available in the Fragment 1.7.0-beta01
release.
th...@outlook.com <th...@outlook.com> #14
Thank you for your work.
Are the changes mentioned in
FATAL EXCEPTION: main
Process: com.example.pbfragmentsharedelement, PID: 3103
java.lang.IllegalStateException: setCurrentPlayTimeMillis() called after animation has been started
at androidx.transition.Transition$SeekController.setCurrentPlayTimeMillis(Transition.java:2778)
at androidx.transition.FragmentTransitionSupport.setCurrentPlayTime(FragmentTransitionSupport.java:265)
at androidx.fragment.app.DefaultSpecialEffectsController$TransitionEffect.onProgress(DefaultSpecialEffectsController.kt:798)
at androidx.fragment.app.SpecialEffectsController.processProgress(SpecialEffectsController.kt:441)
at androidx.fragment.app.FragmentManager$1.handleOnBackProgressed(FragmentManager.java:513)
at androidx.activity.OnBackPressedDispatcher.onBackProgressed(OnBackPressedDispatcher.kt:255)
at androidx.activity.OnBackPressedDispatcher.access$onBackProgressed(OnBackPressedDispatcher.kt:63)
at androidx.activity.OnBackPressedDispatcher$2.invoke(OnBackPressedDispatcher.kt:129)
at androidx.activity.OnBackPressedDispatcher$2.invoke(OnBackPressedDispatcher.kt:127)
at androidx.activity.OnBackPressedDispatcher$Api34Impl$createOnBackAnimationCallback$1.onBackProgressed(OnBackPressedDispatcher.kt:388)
at android.window.WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper.lambda$onBackStarted$0(WindowOnBackInvokedDispatcher.java:329)
at android.window.WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda5.onProgressUpdate(Unknown Source:2)
at android.window.BackProgressAnimator.updateProgressValue(BackProgressAnimator.java:161)
at android.window.BackProgressAnimator.-$$Nest$mupdateProgressValue(Unknown Source:0)
at android.window.BackProgressAnimator$1.setValue(BackProgressAnimator.java:61)
at android.window.BackProgressAnimator$1.setValue(BackProgressAnimator.java:57)
at com.android.internal.dynamicanimation.animation.DynamicAnimation.setPropertyValue(DynamicAnimation.java:731)
at com.android.internal.dynamicanimation.animation.DynamicAnimation.doAnimationFrame(DynamicAnimation.java:687)
at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:344)
at android.animation.AnimationHandler.-$$Nest$mdoAnimationFrame(Unknown Source:0)
at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:87)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1341)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1352)
at android.view.Choreographer.doCallbacks(Choreographer.java:952)
at android.view.Choreographer.doFrame(Choreographer.java:878)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1326)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8248)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
jb...@google.com <jb...@google.com> #15
If you used a snapshot from this morning it should be fixed. Are you doing the same thing in these 3 cases and seeing different results? Could you further explain how you get these 3 cases?
th...@outlook.com <th...@outlook.com> #16
I did use the very latest snapshot version from this morning.
There are 2 different ways to trigger an issue and both issues trigger the same leak from
The first issue, leading to the crash in the stacktrace in
Press the button to open the second fragment and interrupt the opening animation by performing the back gesture (without seeking).
Press the second fragment button again before the closing animation is finished and interrupt the opening animation again using the back gesture.
The second issue, to get into an undefined state, is to:
Press the button to open the second fragment.
Press the back button in the toolbar at the time the opening animation is finishing.
The timing has to be just right but the issue can be triggered fairly consistently.
Both issues can be experienced using the project attached to
jb...@google.com <jb...@google.com> #18
I am closing this as I have not been able to reliably produce any of the mentioned errors with the latest library versions and this bug was about providing support for shared elements, which did. I did see a case where if you use system back to interrupt, that the transition didn't finish, but I couldn't reproduce that either.
If you can provide an app that reproduces this case reliably please file a new bug.
th...@outlook.com <th...@outlook.com> #19
The last issue with predictive back I've come across was fixed in fragment-1.8.5. Thanks for the fixes.
Description
Component used: Fragment
After the release of Android 14 brought predictive back, Material Components added support for Material Motion Transitions . Unfortunately the shared element transition that would bring the coolest effects does not yet work, because the Fragment library does not support predictive back with this type of transition.
This is where I would like to request predictive back support for the shared element transition in the AndroidX Fragment library.
Ref:https://github.com/material-components/material-components-android/issues/3619#issuecomment-1883473193