Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding Android navigation IllegalArgumentException in NavController [duplicate]

Tags:

I recently switched over to Android Navigation, but have encountered a fair amount of situations (in different parts of the code), where I get:

Fatal Exception: java.lang.IllegalArgumentException
navigation destination com.xxx.yyy:id/action_aFragment_to_bFragment is unknown to this NavController

In every case, the code are simple calls like:

findNavController(this, R.id.navigation_host_fragment).navigate(R.id.action_aFragment_to_bFragment)

Usually in response to a button press.

It's unclear why this error is getting thrown. My current suspicion is that the onClickListener is somehow getting called twice on some devices, causing the navigate to be called a second time (causing it to be in the wrong state at the time). The reason for this suspicion is that this most often seems to happen in cases where one might have a "long" running operation before the navigate call. I can't recreate this on my own device, though.

Ideas on how to avoid this issue (or indeed, what the actual root cause of the issue is)?

I don't want to use Global Actions; I'm wary of introducing even more unexpected states to the backstack. And I'd really prefer not to have to try and test for the currentstate every time a navigate call is made.

like image 379
Michael A. Avatar asked Feb 14 '19 11:02

Michael A.


2 Answers

You can use the below code before navigating to check whether the current destination is correct or not. This will make sure that the call happens from the current fragment only. This issue can be reproduced by clicking on two views simultaneously(Two items in a list).

if (findNavController().currentDestination?.id == R.id.currentFragment) {
        findNavController().navigate(R.id.action_current_next)
}
like image 99
Rohit P Soman Avatar answered Sep 18 '22 08:09

Rohit P Soman


Okay, let me explain you this exception was pass because we are calling an action from a fragment(destination) which is not the current destination on the stack.

i.e you're calling an action

R.id.action_aFragment_to_bFragment

from fragmentA but in navController current destination is other that fragmentA. That's why navController through that exception:

navigation destination com.xxx.yyy:id/action_aFragment_to_bFragment is unknown to this NavController

you can check the current destination before navigate. like

 Toast.makeText(context,view?.findNavController()?.currentDestination?.label,Toast.LENGTH_SHORT).show()

That will show you the current destination and i'm sure that's will be some other destination.

This will happens when we replace a fragment other than actions(like via old methods not with navigation) or we popUp that fragment before calling an action.

If that will be the case then you have to use Global Action because they don't care what current destination is.

like image 25
Hussnain Haidar Avatar answered Sep 18 '22 08:09

Hussnain Haidar