Status Update
Comments
[Deleted User] <[Deleted User]> #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
il...@google.com <il...@google.com> #3
ap...@google.com <ap...@google.com> #4
Branch: androidx-master-dev
commit d3c7e85f798b804ef66da955f79f2d162aa20452
Author: Jeremy Woods <jbwoods@google.com>
Date: Tue Dec 17 11:27:36 2019
Ensure StrictFragment does not ascend state with destroyed activity
Added a check to make sure that when a StrictFragment is going up in
state, its activity is not destroyed. Put checks in onCreateView and
onCreatedView of StrictViewFragment too.
Test: all tests pass
BUG: 144309266
Change-Id: Iefe2031c0c40ba603dd83d257a255bf5df278dc3
M fragment/fragment/src/androidTest/java/androidx/fragment/app/StrictViewFragment.kt
M testutils/testutils-runtime/src/main/java/androidx/fragment/app/StrictFragment.kt
ap...@google.com <ap...@google.com> #5
Branch: androidx-master-dev
commit c03c0e0ebfaca4b1b342dad0270489107ea4c73d
Author: Jeremy Woods <jbwoods@google.com>
Date: Tue Dec 17 11:35:33 2019
Change FragmentFinishEarlyTest to use StrictFragment
The goal of the FragmentFinishEarlyTest is to ensure that the Fragment
state is not raised while the activity is being destroyed.
StrictFragment now checks if the activity is being destroyed in all of
the upward states (onCreate, onStart, etc.) so we should just use that
instead of a custom Fragment with booleans.
Test: all tests pass
BUG: 144309266
Change-Id: Ic47a178c50bcbba246b91e2e25d969dd6931d765
M fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentFinishEarlyTest.kt
ap...@google.com <ap...@google.com> #6
Branch: androidx-master-dev
commit 3d9b247656fd46ebd17b1cd9743e163afe85f3d6
Author: Ian Lake <ilake@google.com>
Date: Thu Jan 09 11:15:06 2020
Remove most usages of onActivityCreated()
Update demos and tests to use onViewCreated()
instead of onActivityCreated().
Test: ./gradlew bOS
BUG: 144309266
Change-Id: Icc0d43554f014c42db1068dfe6410cc191e21818
M fragment/fragment/src/androidTest/java/androidx/fragment/app/LoaderTest.kt
M samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentLayoutSupport.java
M samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentListArraySupport.java
M samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentPagerSupport.java
M samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentStatePagerSupport.java
M samples/Support4Demos/src/main/java/com/example/android/supportv4/app/LoaderCursorSupport.java
M samples/Support4Demos/src/main/java/com/example/android/supportv4/app/LoaderCustomSupport.java
M samples/Support4Demos/src/main/java/com/example/android/supportv4/app/LoaderThrottleSupport.java
an...@google.com <an...@google.com> #7
to...@gmail.com <to...@gmail.com> #8
With the removal of this what is the proper and easy way to know when the view is actually attached to parent?
Going edge to edge with BottomSheetDialogFragment force us to get the view parents to disable fitsSystemWindows and handling this properly.
Unfortunately the view is not yet attached during the call to onViewCreated and onActivityCreated is the best place.
From your initial post I suppose onViewStateRestored is the new proper callback, but the name is counter intuitive and I initially thought that this would not have been called on first creation as nothing to restore.
il...@google.com <il...@google.com> #9
Re #8 - onActivityCreated()
runs onViewCreated()
, so the state you're in would be exactly the same between the two calls.
We've been meaning to make it more consistent whether you're attached or not in onViewCreated()
for a while here (as it turns out right now you could be in either case), I've created
to...@gmail.com <to...@gmail.com> #10
It seems the new beta tracker does not automatically watch issues on comment did not receive this answer :(.
Anyway with Fragment 1.2.1 in BottomSheetDialogFragment this is not the case.
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
logError("TAG") { "onActivityCreated: ${view?.parent?.parent?.parent}" }
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
logError("TAG") { "onViewCreated: ${this.view?.parent?.parent?.parent}" }
logError("TAG") { "onViewCreated: ${view.parent?.parent?.parent}" }
}
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
logError("TAG") { "onViewStateRestored: ${this.view?.parent?.parent?.parent}" }
}
Always and consistently gives:
2020-02-10 18:48:24.498 31061-31130/XXX E/TAG: BaseBottomSheetDialogFragment.onViewCreated@63: onViewCreated: null
2020-02-10 18:48:24.499 31061-31130/XXX E/TAG: BaseBottomSheetDialogFragment.onViewCreated@64: onViewCreated: null
2020-02-10 18:48:24.519 31061-31129/XXX E/TAG: BaseBottomSheetDialogFragment.onActivityCreated@58: onActivityCreated: android.widget.FrameLayout{f46459f V.E...... ......I. 0,0-0,0 #7f0a0137 app:id/container}
2020-02-10 18:48:24.520 31061-31129/XXX E/TAG: BaseBottomSheetDialogFragment.onViewStateRestored@70: onViewStateRestored: android.widget.FrameLayout{f46459f V.E...... ......I. 0,0-0,0 #7f0a0137 app:id/container}
to...@gmail.com <to...@gmail.com> #11
So Ian the issue is about DialogFragment:
Seems this is also not changed in your 1.3.0 commit listed here, would be nice that it is and that onViewCreated works in that case too if possible or find a proper common ways that works for all cases.
il...@google.com <il...@google.com> #12
Work hasn't completed on this bug (which is why it isn't marked as 'Fixed') - DialogFragment
is one of the things we're still looking at.
to...@gmail.com <to...@gmail.com> #13
Was just commenting about the fact that those 2 events are not the same for dialog fragment despite the link you gave.
Since I'm rewriting a lot of stuff, I wonder what will be the final target for 1.3?
- onViewCreated will be attached for every cases
- onViewStateRestored will be attached for every cases
- This is still not determined and maybe not done for 1.3 so I should not bother yet.
il...@google.com <il...@google.com> #14
This bug is solely about onActivityCreated
. If you want to talk about onViewCreated
, let's move the conversation onto
If you want a foolproof signal for the View being attached, you should look at the View layer and doOnAttach
from core-ktx
. You don't need anything at the Fragment layer.
to...@gmail.com <to...@gmail.com> #15
I think there's a communication issue here :) My issue is about onActivityCreated
I don't care what is the replacement I just need to know what it will be :)
You tell me that onActivityCreated
and onViewCreated
are the same as called side by side, this is as proven unfortunately not true for dialog fragments that are fragments.
onActivityCreated
is the only callback that is made after the view is properly attached and things are all tied up.
Since you deprecate onActivityCreated
my question is unchanged what is / will be the proper callback for dialog fragment that ensure the same state as currently.
il...@google.com <il...@google.com> #16
I think the main communication issue is that I'm talking about the View moving to the attached state and you're talking about when the view has been added to its parent ViewGroup. While related (a View cannot be attached unless it is added to a ViewGroup that is attached), they are absolutely not the same thing.
For a non-dialog Fragment, the View is added to its container (but not always attached) right before onViewCreated()
is called. onViewCreated()
.
For a dialog Fragment, there is no container. FragmentManager does nothing before onViewCreated()
. This is likely to continue to be the case in Fragment 1.3.0 and beyond. DialogFragment
currently adds the View to the dialog in onActivityCreated()
, but still does not wait for the View to be attached. We'll need to continue to do that for backward compatibility, but will rewrite DialogFragment
to allow for an eventual removal of onActivityCreated()
entirely. That's the work I mentioned in #12.
Like I mentioned, you should really use doOnAttach
in onCreateView
or onViewCreated
if you want to get a callback for when your View has been attached and, by prerequisite, added to its parent. That will work consistently across all cases, Fragment, DialogFragment, or non-Fragment use cases.
to...@gmail.com <to...@gmail.com> #17
Thanks for clarification effectively I had no idea about added to parent being different from attached at the view level. Is there some doc page outside of raw API description that better cover that point?
ap...@google.com <ap...@google.com> #18
Branch: androidx-master-dev
commit f1cf08495ff78c020c05eed5e54ecc550e90c3df
Author: Jeremy Woods <jbwoods@google.com>
Date: Thu Mar 05 14:19:36 2020
Make onActivityCreated optional in DialogFragment
DialogFragment uses onActivityCreated() to help setup the dialog. Since
onActivityCreated() is being deprecated (aosp/1189651) we should find a
better home for the logic executed there.
Code concerning the view has been moved to the observe of the
viewLifecycleOwnerLiveData of the DialogFragment, and other
initialization can be done in onGetLayoutInflater when the Dialog is
initialized.
We will still support dialog setup in onActivityCreated for custom dialogs.
Test: all existing tests pass
BUG: 144309266
Change-Id: I832c596f2a6d6c2a4d77b97df15930d39bdedb9d
M fragment/fragment/src/androidTest/java/androidx/fragment/app/DialogFragmentTest.kt
M fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java
ap...@google.com <ap...@google.com> #19
Branch: androidx-master-dev
commit ab4247a7eb4c1bed603d42d84d8e6c5a5d604f58
Author: Jeremy Woods <jbwoods@google.com>
Date: Thu Mar 05 14:34:39 2020
Deprecate Fragment's onActivityCreated
The original purpose of the onActivityCreated() callback was to allow
fragment logic to be tied to the creation of its activity. We should no
longer be encouraging this coupling.
We should promote passing in external dependencies as construction
parameters using FragmentFactory. Code touching the fragment's view
should be done in onViewCreated() and other initialization code should
be in onCreate(). To receive a callback specifically when the activity's
onCreate() is complete, a LifeCycleObserver should be registered on the
activity's Lifecycle in onAttach(), and removed once the onCreate()
callback is received.
Test: ./gradlew checkApi
BUG: 144309266
Change-Id: Iba62d27bc6b87aa5048315a4cb90e5dcdf550114
M fragment/fragment/api/1.3.0-alpha02.txt
M fragment/fragment/api/current.txt
M fragment/fragment/api/public_plus_experimental_1.3.0-alpha02.txt
M fragment/fragment/api/public_plus_experimental_current.txt
M fragment/fragment/api/restricted_1.3.0-alpha02.txt
M fragment/fragment/api/restricted_current.txt
M fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt
M fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentLifecycleCallbacksDispatcher.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
jb...@google.com <jb...@google.com> #20
This has been fixed internally and will be available in the Fragment 1.3.0-alpha02 release.
sw...@gmail.com <sw...@gmail.com> #21
In my project, I currently use onActivityCreated()
to show/hide the app toolbar (with activity.supportActionBar.show()/activity.supportActionBarHide()).
Is it safe to move that logic to onViewCreated()
(as it is similar as onActivityCreated()
from my understanding of previous comments), or should I add a lifecycle observer on the Activity
?
il...@google.com <il...@google.com> #22
Re #21 - certainly sounds like you want onViewCreated()
.
ch...@gmail.com <ch...@gmail.com> #23
il...@google.com <il...@google.com> #24
Re #23 - sounds like onViewCreated()
is what you're looking for.
Description
Version used: 1.2.0-rc02
onActivityCreated() is a callback provided to Fragments ostensibly for when the activity is finished being created, but it ends up actually being tied into the Fragment view's lifecycle - it is actually called between onViewCreated() and onViewStateRestored() and can be called multiple times in cases where the Fragment is detached/re-attached or moved onto the back stack.
Besides being, at best, confusingly named, the original purpose of giving a callback after the Activity's onCreate() completes indicates a strong coupling between the logic in the Fragment and the logic running in the Activity's onCreate(), which is not a pattern we want to encourage. In general, Fragment should act independently from the Activity, being passed external arguments as constructor parameters via FragmentFactory.
We should deprecate onActivityCreated(), citing that the method is called directly after onViewCreated() and is not a one time call immediately after the activity is created as the name suggests. Code touching the Fragment's view should be in onViewCreated() and other initialization should be done in onCreate(). If the developer specifically wants a callback of when the Activity's onCreate() is complete, they should register a LifecycleObserver on the Activity's Lifecycle, removing it when they receive the onCreate() callback.