Status Update
Comments
jb...@google.com <jb...@google.com> #2
Branch: androidx-main
commit 57ca221882695bd6a52549f4d9ea3b812e6fe87c
Author: Simon Schiller <simonschiller@users.noreply.github.com>
Date: Mon Mar 22 16:09:30 2021
[GH] [FragmentStrictMode] Detect <fragment> tag usage
## Proposed Changes
- Detect `<fragment>` tag usage inside XML layouts
## Testing
Test: See `FragmentStrictModeTest#detectFragmentTagUsage`
## Issues Fixed
Fixes: 153738235
This is an imported pull request from
Resolves #141
Github-Pr-Head-Sha: 4ea052596e4341b9f11bcf335e2bc38045a91f19
GitOrigin-RevId: 62e7487aa4874eef6bb556490e193717cf937251
Change-Id: Iae48578e85e4e4897f806d7ade2e2a660adf9479
M fragment/fragment/api/public_plus_experimental_current.txt
M fragment/fragment/api/restricted_current.txt
M fragment/fragment/src/androidTest/java/androidx/fragment/app/strictmode/FragmentStrictModeTest.kt
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java
M fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentStrictMode.java
A fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentTagUsageViolation.java
dn...@google.com <dn...@google.com> #3
Is there a full example you can link to which shows a shared element transition working with predictive back?
jb...@google.com <jb...@google.com> #4
This one uses Navigation, but the guidance is the same.
Click to go to the second fragment, and dragging back will show the sharedElement box seeking.
th...@outlook.com <th...@outlook.com> #5
Thank you for the sample and the insight it provides.
I added a MaterialToolbar
to the sample project and now some unexpected behaviour is encountered when I perform the back gesture before the animation finished playing. The back arrow and the second fragment label are still displayed in the MaterialToolbar
. I am unsure if this is related to the Navigation
library or the Fragment
library.
th...@outlook.com <th...@outlook.com> #6
Can the above sample please be triaged? There is definitely a bug with shared element transitions in combination with the navigation, but I am unable to tell where exactly things go wrong.
il...@google.com <il...@google.com> #7
Re MaterialToolbar
, you should file an issue on the
th...@outlook.com <th...@outlook.com> #8
The toolbar was for demonstration purposes to visualize the issue and is not causing the actual issue. When downgrading to the latest stable release of the jetpack Fragment library 1.6.2, the issue is resolved but shared element transitions are not supported in this version. Please try the sample I shared and experience it yourself. It definitely needs to be resolved before the stable release of Fragment 1.7.0
I added leakcanary and I think it reveals part of the underlying issue:
┬───
│ GC Root: Thread object
│
├─ java.lang.Thread instance
│ Leaking: NO (the main thread always runs)
│ Thread name: 'main'
│ ↓ Thread.threadLocals
│ ~~~~~~~~~~~~
├─ java.lang.ThreadLocal$ThreadLocalMap instance
│ Leaking: UNKNOWN
│ Retaining 710,0 kB in 1495 objects
│ ↓ ThreadLocal$ThreadLocalMap.table
│ ~~~~~
├─ java.lang.ThreadLocal$ThreadLocalMap$Entry[] array
│ Leaking: UNKNOWN
│ Retaining 710,0 kB in 1494 objects
│ ↓ ThreadLocal$ThreadLocalMap$Entry[10]
│ ~~~~
├─ java.lang.ThreadLocal$ThreadLocalMap$Entry instance
│ Leaking: UNKNOWN
│ Retaining 695,6 kB in 1424 objects
│ ↓ ThreadLocal$ThreadLocalMap$Entry.value
│ ~~~~~
├─ androidx.collection.ArrayMap instance
│ Leaking: UNKNOWN
│ Retaining 695,6 kB in 1423 objects
│ ↓ SimpleArrayMap.mArray
│ ~~~~~~
├─ java.lang.Object[] array
│ Leaking: UNKNOWN
│ Retaining 695,5 kB in 1421 objects
│ ↓ Object[1]
│ ~~~
├─ androidx.transition.Transition$AnimationInfo instance
│ Leaking: UNKNOWN
│ Retaining 32 B in 1 objects
│ ↓ Transition$AnimationInfo.mTransition
│ ~~~~~~~~~~~
├─ androidx.transition.Fade instance
│ Leaking: UNKNOWN
│ Retaining 54,1 kB in 1019 objects
│ ↓ Transition.mParent
│ ~~~~~~~
├─ androidx.transition.TransitionSet instance
│ Leaking: UNKNOWN
│ Retaining 9,8 kB in 264 objects
│ ↓ Transition.mParent
│ ~~~~~~~
├─ androidx.transition.TransitionSet instance
│ Leaking: UNKNOWN
│ Retaining 8,9 kB in 242 objects
│ ↓ Transition.mParent
│ ~~~~~~~
├─ androidx.transition.TransitionSet instance
│ Leaking: UNKNOWN
│ Retaining 8,0 kB in 220 objects
│ ↓ Transition.mEndValuesList
│ ~~~~~~~~~~~~~~
├─ java.util.ArrayList instance
│ Leaking: UNKNOWN
│ Retaining 60 B in 2 objects
│ ↓ ArrayList[4]
│ ~~~
├─ androidx.transition.TransitionValues instance
│ Leaking: UNKNOWN
│ Retaining 120 B in 4 objects
│ ↓ TransitionValues.view
│ ~~~~
╰→ androidx.constraintlayout.widget.ConstraintLayout instance
​ Leaking: YES (ObjectWatcher was watching this because com.example.
​ pbfragmentsharedelement.FirstFragment received Fragment#onDestroyView()
​ callback (references to its views should be cleared to prevent leaks))
​ Retaining 2,6 kB in 55 objects
​ key = ecd720aa-87ad-4a48-b51f-d2a2884cd619
​ watchDurationMillis = 12386
​ retainedDurationMillis = 7385
​ View not part of a window view hierarchy
​ View.mAttachInfo is null (view detached)
​ View.mID = R.id.linearLayout
​ View.mWindowAttachCount = 1
​ mContext instance of com.example.pbfragmentsharedelement.MainActivity
​ with mDestroyed = false
METADATA
Build.VERSION.SDK_INT: 34
Build.MANUFACTURER: Google
LeakCanary version: 2.9
App process name: com.example.pbfragmentsharedelement
Class count: 27517
Instance count: 200528
Primitive array count: 147971
Object array count: 29487
Thread count: 19
Heap total bytes: 27495870
Bitmap count: 1
Bitmap total bytes: 622848
Large bitmap count: 0
Large bitmap total bytes: 0
Stats: LruCache[maxSize=3000,hits=112546,misses=194367,hitRate=36%]
RandomAccess[bytes=9557532,reads=194367,travel=76808102809,range=33363847,size=4
1840281]
Analysis duration: 3619051 ms
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