Warum Android-Navigation fehlschlägt: IllegalArgumentException und NavController

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

„Route verloren“: Warum Android Navigation Component verrücktspielt

\n\n

Haben Sie jemals Ihre Android-App gestartet, zu einem Bildschirm navigiert, auf „Zurück“ gedrückt – und plötzlich stürzte die App mit dem Fehler IllegalArgumentException: navigation destination xxx is unknown to this NavController ab? Falls ja, sind Sie nicht allein. Diese Frage hat tausende Aufrufe auf Stack Overflow gesammelt, und jeder zweite Entwickler, der mit Jetpack Navigation beginnt, stößt darauf.

\n\n

In diesem Artikel analysieren wir, warum IllegalArgumentException navigation destination unknown auftritt, wie man ihn diagnostiziert und vor allem, wie man ihn behebt. Es wird viel lebendigen Kotlin-Code, praktische Tipps und kein „Blabla“ geben. Los geht‘s!

\n\n

Was ist NavController und warum „kennt“ er Ihr Ziel nicht?

\n\n

Zunächst etwas Theorie. NavController ist der Hauptdirigent der Navigation in Android. Er verwaltet Übergänge zwischen Bildschirmen (Fragments oder Composables) basierend auf dem Navigationsgraphen – einer XML-Datei, in der alle möglichen Routen beschrieben sind. Wenn Sie navController.navigate(R.id.some_destination) aufrufen, sucht NavController nach dieser ID in seinem Graphen. Findet er sie nicht, wird eine IllegalArgumentException ausgelöst.

\n\n

Das klingt logisch, aber warum passiert das zur Laufzeit und nicht während der Kompilierung? Weil der Navigationsgraph dynamisch geladen wird und der Fehler oft damit zusammenhängt, dass der aktuelle Graph (den der NavController enthält) das angeforderte Ziel einfach nicht enthält.

\n\n

Die häufigsten Fehlerszenarien

\n
    \n
  • Versuch, zu einem Bildschirm zu navigieren, der nicht im aktuellen Graphen beschrieben ist – z.B. Sie wechseln Fragments, aber der NavController stammt noch vom vorherigen.
  • \n
  • Verwendung von DeepLinks ohne korrekte Registrierung – die App wird über einen Link gestartet, aber der Graph ist noch nicht geladen.
  • \n
  • Leeren des Back Stacks und anschließender Navigationsversuch – der NavController „vergisst“ seine Routen.
  • \n
  • Falsche ID des Ziels – Tippfehler oder Namenskonflikt im Code und XML.
  • \n
\n\n

Analyse an einem realen Beispiel (Kotlin)

\n\n

Stellen Sie sich vor, Sie haben eine App mit zwei Bildschirmen: HomeFragment und ProfileFragment. Der Navigationsgraph nav_graph.xml sieht so aus:

\n\n
<!-- nav_graph.xml -->\n<navigation xmlns:android="http://schemas.android.com/apk/res/android"\n    xmlns:app="http://schemas.android.com/apk/res-auto"\n    android:id="@+id/nav_graph"\n    app:startDestination="@id/homeFragment">\n\n    <fragment\n        android:id="@+id/homeFragment"\n        android:name="com.example.app.HomeFragment"\n        android:label="Home">\n        <action\n            android:id="@+id/action_home_to_profile"\n            app:destination="@id/profileFragment" />\n    </fragment>\n\n    <fragment\n        android:id="@+id/profileFragment"\n        android:name="com.example.app.ProfileFragment"\n        android:label="Profile" />\n</navigation>
\n\n

In HomeFragment führen Sie den Übergang durch:

\n\n
// HomeFragment.kt\nval navController = findNavController()\nnavController.navigate(R.id.action_home_to_profile)
\n\n

Alles funktioniert. Aber was, wenn Sie versuchen, navController.navigate(R.id.profileFragment) aus einem anderen Kontext aufzurufen – z.B. aus der Activity oder einem BroadcastReceiver? Oder wenn Sie den Graphen neu geladen haben? Dann erscheint IllegalArgumentException: navigation destination xxx is unknown to this NavController.

\n\n

Fehler reproduzieren

\n\n

Angenommen, Sie haben eine „Zurück“-Schaltfläche in der Toolbar hinzugefügt und diesen Code geschrieben:

\n\n
// MainActivity.kt\nsupportActionBar?.setDisplayHomeAsUpEnabled(true)\n\noverride fun onOptionsItemSelected(item: MenuItem): Boolean                

Blogs

Buchempfehlungen