具有给定密钥的 SavedStateProvider 已注册
SavedStateProvider with the given key is already registered
我目前正在试用带有 savedState 的新 Jetpack ViewModel。
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-rc01'
我正在使用 1 Activity 并尝试与 2 个片段共享 1 个 ViewModel,但是当我尝试启动第二个片段时,我从标题中得到了错误。
这就是我使用 savedInstance 调用 ViewModel 的方式:
val repository = (activity?.application as App).getRepository()
viewModel = activity?.run {
ViewModelFactory(repository, this, savedInstanceState).create(MainViewModel::class.java)
} ?: throw Exception("Invalid Activity")
这是我的日志:
java.lang.IllegalArgumentException: SavedStateProvider with the given key is already registered
at androidx.savedstate.SavedStateRegistry.registerSavedStateProvider(SavedStateRegistry.java:111)
at androidx.lifecycle.SavedStateHandleController.attachToLifecycle(SavedStateHandleController.java:50)
at androidx.lifecycle.SavedStateHandleController.create(SavedStateHandleController.java:70)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:67)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:84)
at com.xxx.yyy.presentation.details.DetailsFragment.onCreate(DetailsFragment.kt:29)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2586)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:838)
at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1197)
at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1080)
at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:119)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1866)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.run(FragmentManagerImpl.java:150)
它似乎在尝试使用已注册的 SavedState,因此出现错误?我认为这就是图书馆的全部意义所在。任何人都可以帮助或指出如何使用此传递参数到 ViewModel 并使用 savedStateHandle 吗?
您永远不应该自己调用 create
- 这样,您实际上并没有使用已经创建的保留 ViewModel
,导致 AbstractSavedStateViewModelFactory
尝试注册同一个键不止一次。
相反,您应该将 ViewModelFactory
传递给 ViewModelProvider
实例以检索已经存在的 ViewModel 或仅在必要时创建它:
val repository = (activity?.application as App).getRepository()
viewModel = activity?.run {
val factory = ViewModelFactory(repository, this, savedInstanceState)
ViewModelProvider(this, factory).get(MainViewModel::class.java)
} ?: throw Exception("Invalid Activity")
如果您依赖 fragment-ktx
版本 1.1.0
或更高版本,您可以改为使用 by activityViewModels
Kotlin 属性 委托,它懒惰地使用 ViewModelProvider
引擎盖下:
val viewModel: MainViewModel by activityViewModels {
val repository = (activity?.application as App).getRepository()
ViewModelFactory(repository, requireActivity(), savedInstanceState)
}
我目前正在试用带有 savedState 的新 Jetpack ViewModel。
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-rc01'
我正在使用 1 Activity 并尝试与 2 个片段共享 1 个 ViewModel,但是当我尝试启动第二个片段时,我从标题中得到了错误。
这就是我使用 savedInstance 调用 ViewModel 的方式:
val repository = (activity?.application as App).getRepository()
viewModel = activity?.run {
ViewModelFactory(repository, this, savedInstanceState).create(MainViewModel::class.java)
} ?: throw Exception("Invalid Activity")
这是我的日志:
java.lang.IllegalArgumentException: SavedStateProvider with the given key is already registered
at androidx.savedstate.SavedStateRegistry.registerSavedStateProvider(SavedStateRegistry.java:111)
at androidx.lifecycle.SavedStateHandleController.attachToLifecycle(SavedStateHandleController.java:50)
at androidx.lifecycle.SavedStateHandleController.create(SavedStateHandleController.java:70)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:67)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:84)
at com.xxx.yyy.presentation.details.DetailsFragment.onCreate(DetailsFragment.kt:29)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2586)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:838)
at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1197)
at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1080)
at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:119)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1866)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.run(FragmentManagerImpl.java:150)
它似乎在尝试使用已注册的 SavedState,因此出现错误?我认为这就是图书馆的全部意义所在。任何人都可以帮助或指出如何使用此传递参数到 ViewModel 并使用 savedStateHandle 吗?
您永远不应该自己调用 create
- 这样,您实际上并没有使用已经创建的保留 ViewModel
,导致 AbstractSavedStateViewModelFactory
尝试注册同一个键不止一次。
相反,您应该将 ViewModelFactory
传递给 ViewModelProvider
实例以检索已经存在的 ViewModel 或仅在必要时创建它:
val repository = (activity?.application as App).getRepository()
viewModel = activity?.run {
val factory = ViewModelFactory(repository, this, savedInstanceState)
ViewModelProvider(this, factory).get(MainViewModel::class.java)
} ?: throw Exception("Invalid Activity")
如果您依赖 fragment-ktx
版本 1.1.0
或更高版本,您可以改为使用 by activityViewModels
Kotlin 属性 委托,它懒惰地使用 ViewModelProvider
引擎盖下:
val viewModel: MainViewModel by activityViewModels {
val repository = (activity?.application as App).getRepository()
ViewModelFactory(repository, requireActivity(), savedInstanceState)
}