Fixed
Status Update
Comments
il...@google.com <il...@google.com>
ma...@gmail.com <ma...@gmail.com> #2
Yeah, it is our API issue. It is very unclear to developer that this will happen. Should we pass lifecycle as parameter?
ch...@moqi.co.uk <ch...@moqi.co.uk> #3
IMO it is complicated issue/feature.
I see three possible use case scenarios:
1. Single actionBar/toolbar per activity. NavigationUI.setupWithNavController works fine.
2. Every fragment has its own toolbar. NavigationUI.setupWithNavController leaks views. And managing back arrow inside Toolbar is not necessary since it it not going to change.
3. Same toolbar used only for some fragments. Such case can occur when parent fragment has back stack with childFragmenManager.
I am not sure how to solve this best. If SDK user will pass fragmentLifecycle instead of viewLifeCycle then view is still be leaked for some time.
I decided not to use these methods at all because in my case (2nd) it is needed to update Toolbar only once - after Toolbar view create.
I see three possible use case scenarios:
1. Single actionBar/toolbar per activity. NavigationUI.setupWithNavController works fine.
2. Every fragment has its own toolbar. NavigationUI.setupWithNavController leaks views. And managing back arrow inside Toolbar is not necessary since it it not going to change.
3. Same toolbar used only for some fragments. Such case can occur when parent fragment has back stack with childFragmenManager.
I am not sure how to solve this best. If SDK user will pass fragmentLifecycle instead of viewLifeCycle then view is still be leaked for some time.
I decided not to use these methods at all because in my case (2nd) it is needed to update Toolbar only once - after Toolbar view create.
il...@google.com <il...@google.com> #4
Project: platform/frameworks/support
Branch: androidx-master-dev
commit d87596efaefed2570133a883d7c304e9ea95e7a8
Author: Ian Lake <ilake@google.com>
Date: Wed Aug 15 16:04:39 2018
Use WeakReferences in NavigationUI
Avoid storing a strong reference to views
(such as a Toolbar within a Fragment) in
OnNavigatedListeners created by
NavigationUI.
NavigationUI makes an effort to clean up
after itself by removing the
OnNavigatedListener if one of its
WeakReferences was garbage collected.
Test: ran the integration test app
BUG: 111961977
Change-Id: Iea466591cc77e79b3b056108d2818afe22d1ddc6
M navigation/ui/src/main/java/androidx/navigation/ui/NavigationUI.java
https://android-review.googlesource.com/732894
https://goto.google.com/android-sha1/d87596efaefed2570133a883d7c304e9ea95e7a8
Branch: androidx-master-dev
commit d87596efaefed2570133a883d7c304e9ea95e7a8
Author: Ian Lake <ilake@google.com>
Date: Wed Aug 15 16:04:39 2018
Use WeakReferences in NavigationUI
Avoid storing a strong reference to views
(such as a Toolbar within a Fragment) in
OnNavigatedListeners created by
NavigationUI.
NavigationUI makes an effort to clean up
after itself by removing the
OnNavigatedListener if one of its
WeakReferences was garbage collected.
Test: ran the integration test app
BUG: 111961977
Change-Id: Iea466591cc77e79b3b056108d2818afe22d1ddc6
M navigation/ui/src/main/java/androidx/navigation/ui/NavigationUI.java
Description
android.arch.navigation:navigation-fragment-ktx
android.arch.navigation:navigation-ui-ktx
Version used:
1.0.0-alpha05
Devices/Android versions reproduced on:
-SM-A510F, Android 7.0
-Emulator x86_64 API 28
Sample project:
Description:
Having this structure:
nav_graph.xml
<navigation
android:id="@+id/nav_graph"
app:startDestination="@id/startFragment">
<fragment
android:id="@+id/startFragment"
android:name="com.example.navbug.StartFragment"
android:label="StartFragment"
tools:layout="@layout/fragment_start">
<action
android:id="@+id/action_startFragment_to_nested_nav_graph"
app:destination="@id/nested_nav_graph" />
</fragment>
<include app:graph="@navigation/nested_nav_graph" />
</navigation>
nested_nav_graph.xml
<navigation
android:id="@+id/nested_nav_graph"
app:startDestination="@id/nestedStartFragment">
<fragment
android:id="@+id/nestedStartFragment"
android:name="com.example.navbug.NestedStartFragment"
android:label="NestedStartFragment">
<action
android:id="@+id/action_nestedStartFragment_to_nestedSecondFragment"
app:destination="@id/nestedSecondFragment"
app:popUpTo="@+id/nestedStartFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/nestedSecondFragment"
android:name="com.example.navbug.NestedSecondFragment"
android:label="NestedSecondFragment" />
</navigation>
I want to achieve this navigation pattern:
StartFragment => NestedStartFragment => NestedSecondFragment =(back)=> StartFragment
I'm trying to implement this by setting the action NestedStartFragment=>NestedSecondFragment with the options [popUpTo=NestedStartFragment, popUpToInclusive=true], so that the resulting stack would be:
0. NestedSecondFragment
1. NestedNavGraph
2. StartFragment
3. NavGraph
When navigating from NestedStartFragment to NestedSecondFragment, the following execption occurs:
java.lang.IllegalArgumentException: Navigator androidx.navigation.fragment.FragmentNavigator@ccc9092 reported navigation to unknown destination id com.example.navbug:id/nestedSecondFragment
at androidx.navigation.NavController$2.onNavigatorNavigated(NavController.java:142)
at androidx.navigation.Navigator.dispatchOnNavigatorNavigated(Navigator.java:217)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:207)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:45)
at androidx.navigation.NavDestination.navigate(NavDestination.java:407)
at androidx.navigation.NavController.navigate(NavController.java:683)
at androidx.navigation.NavController.navigate(NavController.java:630)
at androidx.navigation.NavController.navigate(NavController.java:618)
at com.example.navbug.NestedStartFragment$onViewCreated$1.onClick(Fragments.kt:31)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Right before the navigation, the stack is:
0. NestedStartFragment
1. NestedNavGraph
2. StartFragment
3. NavGraph
When NestedStartFragment is popped on my request, NestedNavGraph is also popped because
"// We never want to leave NavGraphs on the top of the stack" (from NavController.onNavigatorNavigated)
with the effect that eventually the requested destination NestedSecondFragment is pruned from the graph and cannot be reached anymore.
Unless I'm doing something wrong, it seems that NavGraph automatic popping should be avoided if the final destination actually belongs to it.