Hilt中ViewModel的多个实例



如果之前有人问过这个问题,我深表歉意。我正试图使用dagger-hilt创建一个活动范围内的同一类型视图模型的多个实例,但即使使用不同的自定义默认参数,它每次都会返回相同的实例。我需要所有的视图模型实例都是活动范围的,而不是片段或导航图范围的,因为我需要所有片段来订阅将在活动中接收的更新数据。

(使用Kotlin(

活动代码

@AndroidEntryPoint
class Activity : AppCompatActivity() {
private val vm1:MyViewModel by viewModels(extrasProducer = {
val bundle = Bundle().apply {
putString("ViewModelType", "vm1")
}
MutableCreationExtras(defaultViewModelCreationExtras).apply {
set(DEFAULT_ARGS_KEY, bundle)
}
}) {
MyViewModel.Factory
}
private val vm2:MyViewModel by viewModels(extrasProducer = {
val bundle = Bundle().apply {
putString("ViewModelType", "vm2")
}
MutableCreationExtras(defaultViewModelCreationExtras).apply {
set(DEFAULT_ARGS_KEY, bundle)
}
}) {
MyViewModel.Factory
}
...
}

ViewModel代码

@HiltViewModel
class MyViewModel @Inject constructor(
application: Application,
private val myRepo: MyRepository,
private val savedStateHandle: SavedStateHandle
) : AndroidViewModel(application) {
...
// Define ViewModel factory in a companion object
companion object {
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
val defaultArgs = extras[DEFAULT_ARGS_KEY]
println("extras $extras and default $defaultArgs")
// Get the Application object from extras
val application = checkNotNull(extras[APPLICATION_KEY])
// Create a SavedStateHandle for this ViewModel from extras
val savedStateHandle = extras.createSavedStateHandle()
savedStateHandle.keys().forEach {
println("factory $it, ${savedStateHandle.get<Any>(it)}")
}
return MyViewModel(
application = application,
myRepo = MyRepository(application),
savedStateHandle = savedStateHandle
) as T
}
}
}
}

当我打印出默认参数时,总是返回第一个初始化的视图模型,即使活动中的两个变量都有不同的默认参数,也不会再次初始化。预期结果:具有不同默认参数的新视图模型实例。

我认为这与Viewmodel商店所有者密钥相同有关,但我确实希望Viewmodel商店所有者相同,就像一个新实例一样,如果这有意义的话。

我知道在过去,你可以使用AbstractSavedStateViewModelFactory,或者使用ViewModelProvider.get((的自定义视图模型工厂,但如果不传递ViewModelStoreOwner,我就无法访问ViewModelProvider.gif,而且由于我不想将其传递给工厂,因为它可能会泄露活动,所以我不知道该怎么做。有没有比使用hilt在同一范围内创建同一类型视图模型的多个实例更好的方法?

override val viewModel: MyViewModel by activityViewModels()

创建与活动共存的viewModel实例。

最新更新