Navigation DESTINATION_NAME is unknown to this Nav

2020-08-26 02:14发布

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)

4条回答
姐就是有狂的资本
2楼-- · 2020-08-26 02:25

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.

查看更多
干净又极端
3楼-- · 2020-08-26 02:27

i am use this way

@Override
public void onBackPressed() {

 if(myNavController.getCurrentDestination().getId()==R.id.startDestinationId)
 /** do something */
 else myNavController.popBackStack();

}
查看更多
唯我独甜
4楼-- · 2020-08-26 02:29

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 twice
Navigation.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

查看更多
混吃等死
5楼-- · 2020-08-26 02:39

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>
查看更多
登录 后发表回答