gpt4 book ai didi

android - 抽象保存状态 View 模型工厂 : SavedStateProvider with the given key is already registered

转载 作者:行者123 更新时间:2023-12-04 23:55:46 25 4
gpt4 key购买 nike

虽然是同样的异常,但是我的情况和SavedStateProvider with the given key is already registered不一样因为我正在使用 Nav-graph Scoped ViewModels,

AbstractSavedStateViewModelFactory 与 navGraphViewModels 一起使用时发生异常。
从startFragment,转到FirstPageFragment,navigateUp()回到startFragment,然后再次访问FirstPageFragment ->crash

class FirstPageFragment: Fragment() {

private val myViewModel: MyViewModel by navGraphViewModels(R.id.nav_mission){
MyViewModel.Factory(requireActivity(), "hello world1")
}
...

我的工厂

class MyViewModel(application: Application,
savedStateHandle: SavedStateHandle,
val someString: String) : AndroidViewModel(application){

class Factory(val activity: Activity, val someString: String):
AbstractSavedStateViewModelFactory(activity as SavedStateRegistryOwner, null) {

override fun <T : ViewModel?> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return MyViewModel(activity.application, handle, someString) as T
}
throw IllegalArgumentException("Unable to construct viewmodel")
}
}

...
}

这是我的 navGraph,ViewModel 用于 firstPageFragment 和 SecondPageFragment

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_main_activity"
app:startDestination="@id/startFragment">

<fragment
android:id="@+id/startFragment"
android:name="com.example.savestatehandledemo.StartFragment"
android:label="FirstPageFragment" >
<action
android:id="@+id/action_startFragment_to_nav_mission"
app:destination="@id/nav_mission" />
</fragment>

<navigation android:id="@+id/nav_mission"
app:startDestination="@id/firstPageFragment">
<fragment
android:id="@+id/firstPageFragment"
android:name="com.example.savestatehandledemo.FirstPageFragment"
android:label="FirstPageFragment" >
</fragment>
<fragment
android:id="@+id/secondPageFragment"
android:name="com.example.savestatehandledemo.SecondPageFragment"
android:label="SecondPageFragment" >
</fragment>
</navigation>
</navigation>

我创建了一个最小示例来重现该问题。 https://github.com/yatw/saveStateHandleDemo/tree/master/app/src/main/java/com/example/savestatehandledemo
此异常仅在进入导航图时发生。

请帮忙!

最佳答案

所以我找到了这个异常的原因,我将 Activity 作为 AbstractSavedStateViewModelFactory 中的 SavedStateRegistryOwner 传递。
第二次访问 navGraph 时,我传递了相同的 Activity 和内部类 SavedStateHandleControllerSavedStateRegistry 不知何故已经保存了状态。(请写这部分的人解释并写入文档)

所以传入navGraph getBackStackEntry
更新的 viewModel 工厂

class MyViewModel(application: Application,
savedStateHandle: SavedStateHandle,
val someString: String) : AndroidViewModel(application){

class Factory(val application: Application,
val savedStateRegistryOwner: SavedStateRegistryOwner,
val someString: String):
AbstractSavedStateViewModelFactory(
savedStateRegistryOwner,
null) {

override fun <T : ViewModel?> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return MyViewModel(application, handle, someString) as T
}
throw IllegalArgumentException("Unable to construct viewmodel")
}
}

在 fragment 中使用它

class FirstPageFragment: Fragment() {

private val myViewModel: MyViewModel by navGraphViewModels(R.id.nav_mission){
MyViewModel.Factory(requireActivity().application,
findNavController().getBackStackEntry(R.id.nav_mission),
"hello world1")
}

特别感谢 EpicPandaForce,https://stackoverflow.com/a/61649394/5777189

关于android - 抽象保存状态 View 模型工厂 : SavedStateProvider with the given key is already registered,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69777585/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com