Status Update
Comments
ma...@gmail.com <ma...@gmail.com> #2
The incoming Intent when the exception occurs has:
- data = null
- extra KEY_DEEP_LINK_IDS ("android-support-nav:controller:deepLinkIds") = [R.id.nav_graph_main]
Please note that as far as I'm aware of, I never create any deep link to nav_graph_main. Is there any internal logic that may create a deep link Intent toward the main Activity's NavGraph?
il...@google.com <il...@google.com> #3
You'll get extra KEY_DEEP_LINK_IDS ("android-support-nav:controller:deepLinkIds") = [R.id.nav_graph_main]
if you have a deep link either 1) to the root of your graph or 2) an implicit deep link to a child of your nav_graph_main
on the other apps task stack and the user hits the Up button.
In any case, Navigation should not be crashing when handling a deep link (it should only be printing a INFO
log message saying it is ignoring the deep link). We have logic for doing exactly that, but it seems like that is failing when the deep link is exactly to only the root graph's ID such as in your [R.id.nav_graph_main]
case.
ap...@google.com <ap...@google.com> #4
Branch: androidx-master-dev
commit 7dc495b2120d93246348952b779beb409e18ff46
Author: Ian Lake <ilake@google.com>
Date: Mon Mar 30 16:24:23 2020
Ensure the root graph is matched when deep linking
findInvalidDestinationDisplayNameInDeepLink()
is designed to ensure that each destination in
the deep link is found in the graph.
NavDestination.buildDeepLinkIds() always uses
the parent graph's ID when deep linking to the
start destination of a graph. This means that
the first ID in the deep link array is always the
ID of the root of the graph.
Rather than assume that the root graph always
matches, we should explicitly check that the first
ID matches the ID on the root graph. This is
particularly important in cases where there are
multiple NavHostFragments in the same activity
(either nested or side by side) to ensure that only
the NavHostFragment that has the graph being
deep linked into handles the deep link and the others
properly ignore it (instead of crashing).
Test: newly added test passes
BUG: 147378752
Change-Id: Ic69d684f8886f177c846ea1f62f6e8966b611c72
M navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
M navigation/navigation-runtime/src/androidTest/res/navigation/nav_nested_start_destination.xml
M navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.java
il...@google.com <il...@google.com> #5
This has been fixed internally (you should no longer get any crash from handleDeepLink()
) and will be available in Navigation 2.3.0-alpha05
.
ma...@gmail.com <ma...@gmail.com> #6
il...@google.com <il...@google.com> #7
We're looking to do a Navigation 2.2.2
bug fix release and will include this fix in that.
an...@google.com <an...@google.com> #8
rc...@olx.ph <rc...@olx.ph> #9
Hello, does anyone know the timeline when to release version 2.3.0-alpha05
? Unfortunately we are also encountering this crash in our app. Thank you.
il...@google.com <il...@google.com> #10
rc...@olx.ph <rc...@olx.ph> #11
The crash is gone now, thank you!
ja...@gmail.com <ja...@gmail.com> #12
After upgrading to 2.2.2 i have crash on finding graph.
I/NavController: Could not find destination com.my.app:id/main_navigation in the navigation graph, ignoring the deep link from Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x1040c000 pkg=com.my.app cmp=com.my.app/com.my.app.MainActivity (has extras) }
This is simple deep link to specified fragment. We have nested NavHostFragment
. The fragment i'm deep linking to is in PARENT GRAPH, not the nested one. MainPageFragment
have the nested NavHostFragment
in it, so i guess the graph found is the nested one and so - does not match one that we are looking for.
<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/main_navigation"
app:startDestination="@id/intro_navigation">
<fragment
android:id="@+id/mainPageFragment"
android:name="com.my.app.MainPageFragment"
android:label="MainPageFragment">
<argument
android:name="fromNotification"
android:defaultValue="false"
app:argType="boolean" />
</fragment>
</navigation>
I created this deep link by builder:
NavDeepLinkBuilder(context)
.setGraph(R.navigation.main_navigation)
.setDestination(R.id.mainPageFragment)
.setArguments(bundleOf("fromNotification" to true))
.createPendingIntent()
il...@google.com <il...@google.com> #13
Re #12 - please file a new bug with a sample project that reproduces your issue. It would be expected that you'd see at least one log message if you have nested NavHostFragment
instances with different graphs (the nested graph would ignore deep links to the outer one, as expected).
ja...@gmail.com <ja...@gmail.com> #14
I think that this code breaks down:
NavDestination node = i == 0
? (mGraph.getId() == destinationId ? mGraph : null)
: graph.findNode(destinationId, false);
For some reason it assumes that first deeplink have to be in current mGraph
. Shouldn't it always scan all graphs to look for proper node?
ja...@gmail.com <ja...@gmail.com> #15
I have 2 of such logs, each for every graph. I will try to create project that reproduces this and create new bug
Description
Version used: 2.2.0-rc03
Devices/Android versions reproduced on: can't reproduce
I have a few crash reports about this exceptions, that I can't reproduce in normal conditions and I wonder if this is some corner-case bug.
Stacktrace:
Fatal Exception: java.lang.IllegalStateException: unknown destination during deep link: com.app:id/nav_graph_main
at androidx.navigation.NavController.handleDeepLink(NavController.java:660)
at androidx.navigation.NavController.onGraphCreated(NavController.java:573)
at androidx.navigation.NavController.setGraph(NavController.java:534)
at androidx.navigation.NavController.setGraph(NavController.java:514)
at com.app.view.HomeFragment.prepareNestedNavHost(HomeFragment.java:65)
at com.app.view.HomeFragment.onViewCreated(HomeFragment.java:50)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:304)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1227)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2373)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2108)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2064)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1960)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:418)
I have a main NavHostFragment, hosted in my MainActivity, that owns the "nav_graph_main" graph.
HomeFragment is a destination of "nav_graph_main" and it contains a second NavHost (the "nested" NavHost) to manage navigation between several subscreens together with a BottomNavigationBar (HomeFragment's layout is a NavHostFragment above a BottomNavigatonBar).
The graph of the "nested" navigation ("nav_graph_home") is a separate resource, with no link to the outer "nav_graph_main" graph.
I need to programmatically set the nested graph to the nested NavController, because the start destination practically depends on which bottom navigation tab I want to be selected first.
Therefore, in HomeFragment's onViewCreated, I call the following prepareNestedNavHost:
fun prepareNestedNavHost() {
val startDestination = args.startDestination
val navHostFragment = childFragmentManager.findFragmentById(R.id.navHostHome) as? NavHostFragment
navHostFragment?.navController?.apply {
// I have no other way to know if the graph is not set:
kotlin.runCatching { this.graph }.onFailure {
val nestedGraph = navInflater.inflate(R.navigation.nav_graph_home)
graph.startDestination = startDestination
this.graph = nestedGraph
}
}
}
The only potential reason that came out of my mind is that the nested NavController, sharing the same Activity with the outer NavController, might end up handling an Intent directed to the latter. Is this working as intended?