Home > Mobile >  java.lang.IllegalStateException: Restoring the Navigation back stack failed: destination cannot be f
java.lang.IllegalStateException: Restoring the Navigation back stack failed: destination cannot be f

Time:01-14

I was using Jetpack Navigation Components, the problem occurred while rotating the device!

I was building an application that has three main features. These are onboarding, auth, and main. Every feature has its navigation graph. If it's the first time opening the app, I have to open go with the onboarding graph, If the user is not authenticated, go with auth. Otherwise to main. The problem keeps occurring while rotating the device.

The detailed exception is here:

Process: io.usdaves.chat, PID: 11247
java.lang.RuntimeException: Unable to start activity ComponentInfo{io.usdaves.chat/io.usdaves.chat.application.HostActivity}: java.lang.IllegalStateException: Restoring the Navigation back stack failed: destination io.usdaves.chat:id/navigation_auth cannot be found from the current destination null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4166)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4312)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6468)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6342)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:71)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2571)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8741)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Caused by: java.lang.IllegalStateException: Restoring the Navigation back stack failed: destination io.usdaves.chat:id/navigation_auth cannot be found from the current destination null
at androidx.navigation.NavController.onGraphCreated(NavController.kt:1128)
at androidx.navigation.NavController.setGraph(NavController.kt:1086)
at androidx.navigation.NavController.setGraph(NavController.kt:1039)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.kt:155)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:3090)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:257)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:2884)
at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:252)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:220)
at io.usdaves.chat.application.HostActivity.onCreate(HostActivity.kt:21)
at android.app.Activity.performCreate(Activity.java:8578)
at android.app.Activity.performCreate(Activity.java:8557)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4147)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4312) 
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6468) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6342) 
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:71) 
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2571) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loopOnce(Looper.java:226) 
at android.os.Looper.loop(Looper.java:313) 
at android.app.ActivityThread.main(ActivityThread.java:8741) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067) 

The directions comes from viewModel:

private const val SHOULD_KEEP_SPLASH = "should_keep_splash_saved_state_handle_key"

@HiltViewModel
class HostViewModel @Inject constructor(
    preferences: UserPreferences,
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    val shouldKeepSplash = savedStateHandle.getStateFlow(SHOULD_KEEP_SPLASH, true)

    val navigationDirections = combine(
        preferences.isOnboardingCompleted(),
        preferences.isLoggedIn()
    ) { isOnboardingCompleted, isLoggedIn ->
        when {
            isOnboardingCompleted && isLoggedIn -> NavigateToMainAction
            isOnboardingCompleted -> NavigateToAuthAction
            else -> NavigateToOnboardingAction
        }.also {
            savedStateHandle[SHOULD_KEEP_SPLASH] = false
        }
    }.distinctUntilChanged().shareIn(viewModelScope, Eagerly)
}

I'was sing this sealed class to pass navigations.

sealed class HostNavigationDirections(@NavigationRes val navigationId: Int) {
    object NavigateToOnboardingAction : HostNavigationDirections(R.navigation.navigation_onboarding)
    object NavigateToAuthAction : HostNavigationDirections(R.navigation.navigation_auth)
    object NavigateToMainAction : HostNavigationDirections(R.navigation.navigation_main)
}

Here is the Host Activity.

@AndroidEntryPoint
class HostActivity : AppCompatActivity() {

    private val viewModel: HostViewModel by viewModels()

    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_host)

        val splashScreen = installSplashScreen()
        splashScreen.setKeepOnScreenCondition { viewModel.shouldKeepSplash.value }

        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        navController = navHostFragment.navController

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.navigationDirections.collectLatest { direction ->
                    val authNavGraph = navController.navInflater.inflate(direction.navigationId)
                    navController.graph = authNavGraph
                }
            }
        }
    }

    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp() || super.onSupportNavigateUp()
    }
}

The xml is here:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@ id/auth_fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@ id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navigation_main" />

</FrameLayout>

I did a lot of researchers on this problem but nothing was found.

CodePudding user response:

That was the dumbest question ever. I just had to remove this line:

app:navGraph="@navigation/navigation_main"

Now it's working. Thanks to @ianhanniballake. He saved my life)

  • Related