Status Update
Comments
jb...@google.com <jb...@google.com> #2
kr...@gmail.com <kr...@gmail.com> #3
since it is already marked as deprecated, we can probably do it by now.
kr...@gmail.com <kr...@gmail.com> #4
kr...@gmail.com <kr...@gmail.com> #5
Branch: androidx-master-dev
commit d576cbdc911cba16638a44fd8223391a90a07ef7
Author: Mike Nakhimovich <digitalbuddha@users.noreply.github.com>
Date: Tue Aug 11 09:30:34 2020
[GH] Hide deprecated internal API.
## Proposed Changes
* `RoomDatabase.java` has protected `mCallbacks` field which is leaking in the API docs, we should @Hide it.
## Testing
Test: Ran unit tests locally
## Issues Fixed
Fixes: 76109329
This is an imported pull request from
Resolves #61
Github-Pr-Head-Sha: 6440daa3a63752c7f9d5ba2a390248cd85bc634f
GitOrigin-RevId: fe92d8466a59b44b218b6ca3cbd57dcda17992f7
Change-Id: Id599cdf5b02b32bdae0166266fb7da967598fe92
A room/runtime/api/current.ignore
M room/runtime/api/current.txt
M room/runtime/api/public_plus_experimental_current.txt
M room/runtime/api/restricted_current.txt
M room/runtime/src/main/java/androidx/room/RoomDatabase.java
kr...@gmail.com <kr...@gmail.com> #6
- Adding a dead code can fix the issue.
- Initially haven't tried the code I posted on "Aug 26, 2022 10:14AM" with two actions: 'to_nested_level_2' and 'to_level_2'. I've just tested it and both actions work correctly, but this is because the code contains the line "<include app:graph="@navigation/level_2_graph" />" which fixes the issue even if it is added as a dead code.
- The issue occurs only for some kinds of >>destinations<<, while it does not occurs for others. The backstack may be empty.
Please, don't close the issue until you investigate it.
jb...@google.com <jb...@google.com> #7
My suggestion pointed you to the root of the problem, which is that you are popping all of the destinations of a graph off the back stack with the popUpTo
set the graph id. So when your to_level_2
action attempts to popUpTo
level_1_graph
it no longer exist.
As part of the work that went into multiple back stacks which was introduced in Navigation 2.4
, it was ensured that any graph that does not have an associated destination is not kept on a back stack as it does not actually represent a location that you can go back to since graphs cannot be displayed.
With that change in mind, the code here is doing exactly what you are telling it to do, which is to pop off all the graph's destinations off the back stack, at which point Navigation automatically also removes the graph. You then try to do another navigate call, telling it to popUpTo
a graph that no longer exists on the back stack, hence the error.
My suggestion of changing the popUpTo
to use the start destination was under the assumption that you actually intended for the graphs to remain in your back stack and you wanted a destination associated with them since having only a graph in the back stack is not very useful.
kr...@gmail.com <kr...@gmail.com> #8
Hi, thank you for your answer. Unfortunately, I think there are still two things which contradicts some of your thoughts:
1.
If the destination of to_level_2
is a Fragment, not some included graph, everything works fine. It means, that the problem is not a missing level_1_graph
or an empty backstack. Even if the graph is empty and level_1_graph
is removed the navigation is still possible to SOME kinds of destinations. Please read the following code:
This will work:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/level_1_graph"
app:startDestination="@id/level_1_fragment">
<fragment
android:id="@+id/level_1_fragment"
android:name="com.example.nestedpopupto.Level1Fragment"
tools:layout="@layout/fragment_level_1">
<action
android:id="@+id/to_level_2"
app:popUpTo="@id/level_1_graph"
app:destination="@id/level_2" /> <!-- <<< This action WILL work <<< -->
</fragment>
<navigation
android:id="@+id/level_2"
app:startDestination="@id/level_2_fragment"> <!-- <<<< The startDestination is a Fragment <<< -->
<fragment
android:id="@+id/level_2_fragment"
android:name="com.example.nestedpopupto.Level2Fragment"
tools:layout="@layout/fragment_level_2" />
</navigation>
</navigation>
While this won't work:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/level_1_graph"
app:startDestination="@id/level_1_fragment">
<fragment
android:id="@+id/level_1_fragment"
android:name="com.example.nestedpopupto.Level1Fragment"
tools:layout="@layout/fragment_level_1">
<action
android:id="@+id/to_level_2"
app:popUpTo="@id/level_1_graph"
app:destination="@id/level_2" /> <!-- <<< This action WON'T work, although it is the same as in the previous code snippet << -->
</fragment>
<navigation
android:id="@+id/level_2"
app:startDestination="@id/level_2_graph"> <!-- <<<< The startDestination is an included graph -->
<include app:graph="@navigation/level_2_graph" />
</navigation>
</navigation>
As you can see, the only difference is the content of "<navigation android:id="@+id/level_2".
2.
Adding dead/empty code solves the issue. Again, this an indication that there is something really wrong.
This will work:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/level_1_graph"
app:startDestination="@id/level_1_fragment">
<fragment
android:id="@+id/level_1_fragment"
android:name="com.example.nestedpopupto.Level1Fragment"
tools:layout="@layout/fragment_level_1">
<action
android:id="@+id/to_level_2"
app:popUpTo="@id/level_1_graph"
app:destination="@id/level_2" />
</fragment>
<navigation
android:id="@+id/level_2"
app:startDestination="@id/level_2_graph">
<include app:graph="@navigation/level_2_graph" />
</navigation>
<include app:graph="@navigation/level_2_graph" />
</navigation>
Even if we assume that we are trying to do something which you no longer support, theres is still a problem with the lib, because it behaves in inconsistent way:
*
If the startDestination oflevel_2
graph is a Fragment everything works fine, while if the startDestination oflevel_2
is a graph, the app crashes.*
Adding dead/unused the code magically "solves" the issue (I would not focus on this one too much)
I suggest to move the focus from what we are doing wrong (trying to use no longer supported feature) to why the lib can still navigate to SOME kind of destinations and not to the others when popUpTo
is used. It clearly contradicts what you are trying to tell us (that the navigation is impossible because the backstack is empty and level_1_graph
is no longer there).
jb...@google.com <jb...@google.com>
ap...@google.com <ap...@google.com> #9
Branch: androidx-main
commit fec95ed9a91ef4058d5265e2f7ba1240db4f651d
Author: Jeremy Woods <jbwoods@google.com>
Date: Mon Aug 29 19:09:30 2022
Fix double nested graph popUpTo behavior
Navigation should always maintain the path to current destination as
part of that back stack. Under normal circumstances following the
recommended behavior this is true.
It is possible to create a scenario where this is not the case.
Given the following graph:
A
|
B
/ \
C D
|
E
|
F
Where C is the start destination of graph B, if you navigate to D while
popping C off the back stack (which is not recommended), Navigation
fails to build the proper hierarchy for D resulting in B being popped
incorrectly and causing an IllegalStateException.
We should ensure that Navigation properly handles nested destinations.
RelNote: "Fixed `IllegalStateException` caused by navigating to a double
nested graph that shares a parent with a new popped start destination."
Test: added testLifecycleDoubleNestedGraph
Bug: 243778589
Change-Id: I9f7cb2445e6021c6ab4cb81d62612411249c1257
M navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
M navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
jb...@google.com <jb...@google.com> #10
I was able to find that is this particular case Navigation is indeed losing the proper back stack.
Again, this is not something we recommend doing when using Navigation as the startDestination is meant to be the entry and exit point of a particular graph. If this is something that the app needs, it might be a sign that the architecture needs to be re-evaluated.
This has been fixed and will be a part of the Navigation 2.5.2
and 2.6.0-alpha01
releases.
kr...@gmail.com <kr...@gmail.com> #11
Thank you! Have a nice day :)
na...@google.com <na...@google.com> #12
This bug was linked in a change in the following release(s):
androidx.navigation:navigation-runtime:2.6.0-alpha01
androidx.navigation:navigation-runtime:2.5.2
Description
Version used: every version since 2.4.0 (latest tested version is 2.5.1)
Latest version working correctly: 2.3.5
Devices/Android versions reproduced on: Emulator API 30, Oppo CPH2251 API 30, Samsung Galaxy S21 API 31
Repro steps:
1. Define the following 3 graphs (sample project is attached to this bug report):
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="
xmlns:app="
xmlns:tools="
android:id="@+id/level_0_graph"
app:startDestination="@id/level_0_fragment">
<fragment
android:id="@+id/level_0_fragment"
android:name="com.example.nestedpopupto.Level0Fragment"
tools:layout="@layout/fragment_level_0">
<action
android:id="@+id/to_level_1"
app:popUpTo="@id/level_0_graph"
app:destination="@id/level_1" />
</fragment>
<navigation
android:id="@+id/level_1"
app:startDestination="@id/level_1_graph">
<include app:graph="@navigation/level_1_graph" />
</navigation>
</navigation>
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="
xmlns:app="
xmlns:tools="
android:id="@+id/level_1_graph"
app:startDestination="@id/level_1_fragment">
<fragment
android:id="@+id/level_1_fragment"
android:name="com.example.nestedpopupto.Level1Fragment"
tools:layout="@layout/fragment_level_1">
<action
android:id="@+id/to_level_2"
app:popUpTo="@id/level_1_graph"
app:destination="@id/level_2" />
</fragment>
<navigation
android:id="@+id/level_2"
app:startDestination="@id/level_2_graph">
<include app:graph="@navigation/level_2_graph" />
</navigation>
</navigation>
<navigation xmlns:android="
xmlns:app="
xmlns:tools="
android:id="@+id/level_2_graph"
app:startDestination="@id/level_2_fragment">
<fragment
android:id="@+id/level_2_fragment"
android:name="com.example.nestedpopupto.Level2Fragment"
tools:layout="@layout/fragment_level_2">
</fragment>
</navigation>
2. Use "to_level_1" to navigate to nested graph.
3. Use "to_level_2" action.
Result:
The action "to_level_2" will fail with the following stacktrace:
java.lang.IllegalArgumentException: No destination with ID 2131230965 is on the NavController's back stack. The current destination is Destination(com.example.nestedpopupto:id/level_2_fragment) class=com.example.nestedpopupto.Level2Fragment
at androidx.navigation.NavController.getBackStackEntry(NavController.kt:2209)
at androidx.navigation.NavController.addEntryToBackStack(NavController.kt:1918)
at androidx.navigation.NavController.addEntryToBackStack$default(NavController.kt:1813)
at androidx.navigation.NavController$navigate$4.invoke(NavController.kt:1721)
at androidx.navigation.NavController$navigate$4.invoke(NavController.kt:1719)
at androidx.navigation.NavController$NavControllerNavigatorState.push(NavController.kt:287)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.kt:246)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.kt:162)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.kt:83)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.kt:49)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.kt:83)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.kt:49)
at androidx.navigation.NavController.navigateInternal(NavController.kt:260)
at androidx.navigation.NavController.navigate(NavController.kt:1719)
at androidx.navigation.NavController.navigate(NavController.kt:1545)
at androidx.navigation.NavController.navigate(NavController.kt:1472)
at androidx.navigation.NavController.navigate(NavController.kt:1930)
at com.example.nestedpopupto.Level1Fragment.onViewCreated$lambda-0(Level1Fragment.kt:13)
The crash will NOT occur if any of the following is applied:
- the "to_level_2" action does not use "popUpTo"
- the "level_2_graph" is not wrapped with the <navigation>.
As one can see the "to_level_1" action is identical to the "to_level_2" action and is defined in an identical graph and it works correctly. It seems that the bug occurs only when navigation is performed in the graph that is included in an other graph.
In the end I would like to remind that everything works correctly with version 2.3.5 of the androidx.navigation.