问题
I am using Navigation Component in my app , recently it was working correctly but after updating project to AndroidX
I am getting error navigation destination DESTINATION_NAME is unknown to this NavController
only if that destination(Which I'm going to open) is previously closed from itself using navController.popBackStack()
. Also, There is no error if I close DESTINATION fragment from MainActivity
, But Error only Occurs fragment is closed from itself using popBackStack
. like below
DestinationFragment
viewModelOfActivity.handleBackButton.observe(this, Observer {
Navigation.findNavController(requireActivity(), R.id.main_nav_host).popBackStack()
//CALLING popBackStack() HERE CAUSING PROBLEM WHEN REOPNING THIS DESTINATION(or frg ) AGIAN
})
MainActivity
override fun onBackPressed() {
if (myViewModel.isDefaultBehaviour.value == true) {
super.onBackPressed()
} else{
myViewModel.handleBackButton.value=true
//NO ERROR IF HANDLE BACK BUTTON HERE ie->findNavController(R.id.main_nav_host).popBackStack()
//INSTEAD OF myViewModel.handleBackButton
}
}
I Have also checked related Question but no help Similar Question.
NOTE: I am using the latest version of the navigation library (alpha05)
回答1:
The previous value likely still exists in the view model and is triggering right away. I'd recommend using an interface to handle your back button delegation instead of an observer. That should fix the usage.
What's happening is you're popping too far up your back stack to the point where you don't have an active graph anymore. This is happening because your observer is getting triggered more often than it should. To see this, I'd recommend debugging that line and inspecting the graph right before a crash. It's likely to be null.
回答2:
I was using SingleLiveEvent in DestinationFragment to observe back press from MainActivity as I have already mentioned this in my question. So the problem was in SingleLiveEvent
I noticed that I have accidently changed code of fun observe(owner: LifecycleOwner, observer: Observer<in T>)
to
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)//Here is problem I was calling super twice in function
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
super.observe(owner, Observer { t ->/** other code*//})
}
Here you can see I was calling super
function twice which calls onChanged
of observer twice in Fragment
, below code is called twiceNavigation.findNavController(requireActivity(), R.id.main_nav_host).popBackStack()
which popBackStack()
twice.
Then I have changed observe
function like below
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
super.observe(owner, Observer { t ->/** other code*//})
}
Now my code works fine
回答3:
I had the same issue. In my app there were three fragments A -> B -> C
and I had to return to A
from C
. In my case I used popBackStack()
to close the current fragment and return to the previous one, after that any attempt to navigate from A
threw Navigation xxx is unknown to this NavController
exception.
I ended up using navigate()
to A
instead of pop fragments from back stack. Using popUpTo
and popUpToInclusive
settings properly fixed the issue (see docs https://developer.android.com/guide/navigation/navigation-getting-started#popupto_example_circular_logic)
<fragment
android:id="@+id/FragmentC"
android:name="xxx.FragmentC"
android:label="C" >
<action
android:id="@+id/action_to_A"
app:destination="@id/FragmentA"
app:popUpTo="@+id/FragmentA"
app:popUpToInclusive="true" />
</fragment>
回答4:
i am use this way
@Override
public void onBackPressed() {
if(myNavController.getCurrentDestination().getId()==R.id.startDestinationId)
/** do something */
else myNavController.popBackStack();
}
来源:https://stackoverflow.com/questions/51887968/navigation-destination-name-is-unknown-to-this-navcontroller-reopening-fragment