Jetpack navigation: Pitfalls and recommendations

Hamza
3 min readJan 21, 2022

--

Source: Pexels

I’ve used Jetpack Compose in a production app for about 4 months now, and in that time, I’ve experienced all manner of emotions. Most times, it’s relief and excitement at how fast it is to create views and reuse components. On the other hand, it is pain, and one of the main sources other than how slow and resource intensive the preview rendering is, has been the Jetpack navigation library.

Don’t get me wrong, it’s not all gloom and doom. I genuinely love how simple navigation is in Compose. It’s just that the pitfalls are unforgiving and hard to predict without prior experience.

In the post, I’ll be outlining some of the common pitfalls, how to solve them and some other interesting tips I’ve come and across or used in my projects.

  • Save the routes as constants.
    You can do this with an object and group them with a sealed class. Why? Not doing this exposes one to the risk of misspelling the routes and causing this exception to be thrown.

java.lang.IllegalArgumentException: Navigation destination that matches request … cannot be found in the navigation graph …

In addition, a sealed class can help with grouping related destination routes for clarity. You can also add a prefix to your routes to distinguish routes with similar names or use-cases.

const val SALES_DETAILS = "sales.detailsPage"
const val SPEND_DETAILS = "spend.detailsPage"
composable("$SALES_DETAILS") {
...
}
navController.navigate("$SALES_DETAILS")
  • Be wary of the ? and & when passing parameters via the routes.
    I’ve found myself using the ? multiple times in the same route for more than 1 parameter, causing an error to occur. You can create a route Builder class or use a library that safely generates routes.
  • You should URLEncode any parameter you are passing via the routes.
    This is important because, if your route contains ?, & ,/ or any other URL related special characters, your route will interpret them not as mere strings but as route delimiters. This can cause the navigation to break. If you pass non-primitive parameters by serialising to JSON Strings, then you have to do this. Don’t forget to URLDecode the parameters when you extract them.
  • Use subgraphs as much as you can, for your sanity.
    With a single, flat graph, your files can get really large, making it difficult to find stuff. Subgraphs are nice and with Hilt, you can create ViewModels scoped to your subgraphs in case you need to share data across its destinations. Ian Lake explains how here.
  • Use JetPack Compose Navigation Material
    Using the Jetpack Compose Navigation Material library simplifies your graph by making your BottomSheets mere destinations like your other ‘full screen’ destinations (s/o Jossi Wolf for this one). The original way works but it makes the graph clunky, especially when you have to display multiple BottomSheets in the same root. Your graph gets longer and you have to write extra code to manage the state of your many BottomSheets.
  • Subscribe to Mark Murphy’s JetC’s newsletter
    Lastly, I’d recommend you subscribe to Mark Murphy’s JetC newsletter. It contains a lot of useful information about Jetpack Compose from all over the internet, especially the #kotlinlang Slack channel. Trust me, you won’t regret it.

--

--