I'm initialising a graph in Activity using Kotlin DSL and using navGraphViewModels() to acquire an instance of vm in the onCreate() of the fragment. However after process death the app crashes
Caused by: java.lang.IllegalArgumentException: No destination with route main_navigation is on the NavController's back stack. The current destination is null
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navController = (supportFragmentManager
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController
val graph = navController.createGraph(
startDestination = "MyFragment1", route = "main_navigation"
) {
fragment<MyFragment1>("MyFragment1") {
deepLink("fi://fragment1")
argument("testing") {
type = NavType.StringType
defaultValue = "hello"
}
}
navigation("MyFragment2", "included_graph") {
fragment<MyFragment2>("MyFragment2") {
deepLink("fi://fragment2")
argument("testing") {
type = NavType.StringType
nullable = true
}
}
}
}
navController.graph = graph
}
MyFragment1.kt
private val vm: Vm by navGraphViewModels("main_navigation")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
vm.someFunction()
}
Stacktrace
Caused by: java.lang.IllegalArgumentException: No destination with route main_navigation is on the NavController's back stack. The current destination is null
at androidx.navigation.NavController.getBackStackEntry(NavController.kt:2472)
at com.example.testingnavigation.MyFragment1$special$$inlined$navGraphViewModels$default$1.invoke(NavGraphViewModelLazy.kt:209)
at com.example.testingnavigation.MyFragment1$special$$inlined$navGraphViewModels$default$1.invoke(NavGraphViewModelLazy.kt:208)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at androidx.navigation.NavGraphViewModelLazyKt.navGraphViewModels$lambda-3(NavGraphViewModelLazy.kt:208)
at androidx.navigation.NavGraphViewModelLazyKt.access$navGraphViewModels$lambda-3(NavGraphViewModelLazy.kt:1)
at com.example.testingnavigation.MyFragment1$special$$inlined$navGraphViewModels$default$4.invoke(NavGraphViewModelLazy.kt:217)
at com.example.testingnavigation.MyFragment1$special$$inlined$navGraphViewModels$default$4.invoke(NavGraphViewModelLazy.kt:214)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:47)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:35)
at com.example.testingnavigation.MyFragment1.getVm(MyFragment1.kt:26)
at com.example.testingnavigation.MyFragment1.onCreate(MyFragment1.kt:30)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:3094)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:504)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:268)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:122)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1455)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3034)
at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:2941)
at androidx.fragment.app.Fragment.restoreChildFragmentState(Fragment.java:1989)
at androidx.fragment.app.Fragment.onCreate(Fragment.java:1967)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.kt:163)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:3094)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:504)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:268)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:114)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1455)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3034)
at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:2941)
14:03:56.302 E at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:252)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:219)
at com.example.testingnavigation.MainActivity.onCreate(MainActivity.kt:17)
at android.app.Activity.performCreate(Activity.java:8119)
at android.app.Activity.performCreate(Activity.java:8103)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1359)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3713)
... 11 more
Steps to reproduce the crash
- Open app and put the app to background
- then use this command
adb shell am kill <package_name> - relaunch app from app icon.
It doesn't crash when directly setting the navgraph in the activity_main.xml layout file.
Whats the right way to use the navigation via kotlin DSL?
onCreatefor Fragments run before the rest of your code inonCreateof your activity. What isviewModel.someFunction()and why is it inonCreate()? Why isn't it in theinitblock of your ViewModel or inonViewCreated?DefaultLifecycleObserverand make an API call inonCreate(). Also, register the VM as lifecycle observer in the fragment's onCreate.onCreate, which is still too early. If you have an actual concrete example, that would be helpful in pointing to what you should actually be doing.onCreate(). But in this case, lets say I'm making an API call which is meant to load the content of the screen. Also, whats the general recommendation of usage of navgraph scoped view model when using kotlin dsl nav graph?