gpt4 book ai didi

mvvm - 使用 Dagger 时我们真的需要 viewModelFactories 和 viewmodelProviders 吗?

转载 作者:行者123 更新时间:2023-12-03 10:56:11 25 4
gpt4 key购买 nike

所以我正在使用 Dagger 开发一些示例 MVVM 项目。我有一个像这样的 View 模型工厂:

class DaggerViewModelFactory @Inject constructor(private val viewModelsMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) :
ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val creator = viewModelsMap[modelClass] ?:
viewModelsMap.asIterable().firstOrNull {
modelClass.isAssignableFrom(it.key)
}?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
return try {
creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}

View 模型工厂模块
@Module
abstract class ViewModelFactoryModule {
@Binds
abstract fun bindViewModelFactory(viewModelFactory: DaggerViewModelFactory): ViewModelProvider.Factory
}

我有一个 ViewModelModule:
@Module
abstract class MyViewModelModule {
@Binds
@IntoMap
@ViewModelKey(TakePicturesViewModel::class)
abstract fun bindTakePictureViewModel(takePicturesViewModel: TakePicturesViewModel): ViewModel
}

一个像这样的组件:
@PerActivity
@Subcomponent(modules = [ActivityModule::class, ViewModelFactoryModule::class, MyViewModelModule::class])
interface ActivityComponent {
fun inject(mainActivity: MainActivity)
}

一个像这样的 View 模型:
class TakePicturesViewModel @Inject constructor(app: Application): AndroidViewModel(app) {...

所以我可以使用这样的 View 模型工厂在我的事件中注入(inject)我的 View 模型:
    @Inject
lateinit var viewModelFactory: DaggerViewModelFactory
private lateinit var takePicturesViewModel: TakePicturesViewModel
.
.
.
takePicturesViewModel = ViewModelProviders.of(this, viewModelFactory).get(TakePicturesViewModel::class.java)

或者根本没有 viewmodel 工厂,像这样:
@Inject
lateinit var takePicturesViewModel: TakePicturesViewModel

两种方式都有效,所以我想知道哪一种是正确的工作方式,如果使用 Dagger 允许我在不需要 viewmodelfactory 的情况下注入(inject) viewmodel,是否有充分的理由保留它?或者我应该摆脱这个 viewmodelfactory ?

提前感谢您的任何建议。

问候

最佳答案

Both ways work, so I was wondering which one is the right way to work, if using Dagger allows me to inject a viewmodel without needing a viewmodelfactory, is there a good reason to keep it?, or should I just get rid of this viewmodelfactory?



两种方式的工作方式不同。尝试使用 ViewModel 中存储的数据旋转屏幕,您会看到。

Dagger 可以创建 ViewModel,这是您在通用 ViewModelFactory 中使用的。这些 View 模型应该是无范围的,因此您每次都将创建一个新的 ViewModel。 Android 支持库将缓存该 ViewModel 并在轮换后重用它,以便您可以保留数据——工厂方法被调用一次,并且只会创建一个 ViewModel(每个生命周期)。您保留数据,一切都按预期运行。

另一方面,如果您使用 Dagger 直接注入(inject)您的 ViewModel,则上述任何一项都不适用。与任何其他依赖项一样,新的 ViewModel 将在创建时注入(inject),导致每次使用时都会创建一个 ViewModel——您不仅会使用存储在其中的数据,而且无法与 Fragment 共享状态任何一个。

当然,您可以将范围应用于 ViewModel,但该范围应该比 Activity 实例的生命周期更长(以保持旋转之间的状态),但不会比屏幕可见长。因此,您既不能将其范围限定为事件,也不能限定于应用程序生命周期。您可以通过在两者之间引入一个新范围来使其工作,但此时您将重新发明 ViewModel 库。

tl;博士注入(inject)并使用工厂,否则你会得到一个令人困惑/错误的 ViewModel 实现。

关于mvvm - 使用 Dagger 时我们真的需要 viewModelFactories 和 viewmodelProviders 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60141954/

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