Sean
Sean

Reputation: 3095

NavController currentDestination is null?

I am using NavController to manages app navigation:

findNavController().navigate(action)

I got a few crashes in Crashlytics: I found it is because:

MyFragment {
     ...
    myLiveData.observer(viewLifecycleOwner, Observer) {
    
        findNavController().navigate(myAction) // currentDestination is null ...
     })
     ...

navController.currentDestination? is an optional, When it is null, app crashes with unhandled exception.

Since currentDestination is declared as optional, I guess there must be some legit reason why it could be null, that I don't know. Appreciate in advance for any pointer.

Upvotes: 1

Views: 2699

Answers (3)

FiveSpotCharlie
FiveSpotCharlie

Reputation: 21

I was experiencing the same issue. At seemingly random times, the navigate to my destination fragment would crash due to the currentDestination being null.
Similar to the OP, I was triggering the nav through a Flow (not a live data).
Despite collecting the flow with the viewLifecycleOwner, it almost seemed like the fragment wasn't ready to navigate. What I found that fixed the issue was a little surprising. It was how the previous fragment was "popping" itself.

FragA -> FragB
FragB.popBackStack()
FragA -> VERY Quickly re-nav to FragB (null currentDestination == Crash)

However, as a test, I tried using

FragB.popBackStack(fragA.id, false)

And the crashes stopped. The currentDestination was never null again. This must be a bug in the navComponent library.

My fix was as follows, and is still working (fingers crossed). Instead of "findNavController.popBackStack()" I use

findNavController().previousBackStackEntry?.let {
    findNavController().popBackStack(it.destination.id, false)
} ?: run {
    findNavController().popBackStack()
}

Hope that works for someone else also.

edit Left in for posterity.. but.. I was wrong. this didn't fix it afterall. My mistake. Carry on.

Upvotes: 2

user2234454
user2234454

Reputation: 1

Thanks Stachu, any relationship to fragment viewLifecycle?

In my case, the navigation is triggered from a liveData observer, i.e.,

MyFragment {
 ...
myLiveData.observer(viewLifecyucleOwner, Observer) {

    findNavController().navigate(myAction) // currentDestination is null ...
 }
 ...

Upvotes: -1

Stachu
Stachu

Reputation: 1724

Destination represents the node in the NavGraph that's being hosted by the NavHost. NavController just manages the flow. There are few ocasions when NavHost is not showing any destination e.g.:

  • before you set the NavGraph (because destination represents position in the graph)
  • when you manually inflate something in the NavHost using transaction (outside of the graph's scope)

If you have multiple graphs in one app (e.g. nested graphs, but can also be independent) you may have one NavController giving main graph destination and a secondary one returning null, etc.

Upvotes: 0

Related Questions