HAX*_*AXM 13 lifecycle android mvvm viewmodel kotlin
我最近开始使用 ViewModel 和 AndroidViewModel,我发现有不同的方法来初始化 viewModel 实例,对我来说一切都很好,我只是想知道何时使用哪一种?我应该在哪里初始化 viewModel 对象?以下是获取 viewModel 实例的不同方法,并且对我有用:
val myViewModel1 = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)
val myViewModel2 = ViewModelProvider.AndroidViewModelFactory(this.application).create(MyViewModel::class.java)
val myViewModel3 = ViewModelProvider(this).get(MyViewModel::class.java)
val myViewModel4: MyViewModel by viewModels()
val myViewModel5 by viewModels<MyViewModel>()
Run Code Online (Sandbox Code Playgroud)
对我来说最简单和最简单的是第三、第四和第五,但是我不知道这五种方法有什么区别,也请让我知道是否有其他方法或最佳方法来初始化我的 viewModel 对象,我在声明全局变量时对其进行初始化,可以在声明时初始化还是应该在某个生命周期方法内完成?
HAX*_*AXM 26
如果有人寻找深入的答案,请检查这个,这里我们有以下方法来创建或获取 viewModel 对象:
val myViewModel1 = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)
myViewModel2 = ViewModelProvider.AndroidViewModelFactory(this.application).create(MyViewModel::class.java)
val myViewModel3 = ViewModelProvider(this).get(MyViewModel::class.java)
val myViewModel4: MyViewModel by viewModels()
val myViewModel5 by viewModels<MyViewModel>()
所有人都做同样的事情,唯一的两个关键区别是:
让我们看看这个lazy loading and without lazy loading,前三个没有委托by,这意味着该对象没有延迟加载,因此开发人员有责任仅在创建活动或片段附加到活动时创建 viewModel 对象,这意味着前三种方法(1、2、3)不能在全局范围内使用,如果在全局范围内使用,变量必须是带有lateint或 null 初始化的 var,并且初始化(方法 1、2、3)必须发生在onCreate 或 onViewCreated(如果是片段)。
因此,创建 viewModel 对象的最佳方法是使用委托by(4, 5),两者相同,但语法略有不同,我选择 4,因为它简单且可读。
val myViewModel4: MyViewModel by viewModels()
Run Code Online (Sandbox Code Playgroud)
委托by提供了延迟加载实例的灵活性,您可以在全局范围内定义 viewModel 并摆脱样板代码,如果您尝试在没有委托的情况下在全局范围内初始化 viewModel,则应用程序将崩溃,因为 viewModel 将尝试在创建活动之前初始化(它不会延迟加载 viewModel 实例)。
现在让我们看看如何使用多个参数来延迟加载,该6th方法在问题中没有提到。
如果视图模型中有多个参数并且不使用任何依赖注入,则可以使用 ViewModelFactory 实现,然后延迟加载它:
val myViewModelWithParm: MyViewModel by viewModels { MyViewModelFactory(application, "param1", "param2") }
Run Code Online (Sandbox Code Playgroud)
ViewModelFactory 实现:
class MyViewModelFactory(val application: Application, val param1: String, val param2: String) :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return MyViewModel(application, param1, param2) as T
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我们已经清楚了委托初始化(4, 5),以及它与(1, 2, 3) 有何不同,现在让我们看看前3 种方法(1, 2, 3) 的区别。
我们首先检查 1 和 2。
val myViewModel1 = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)myViewModel2 = ViewModelProvider.AndroidViewModelFactory(this.application).create(MyViewModel::class.java)它们之间的关键区别是一个用途ViewModelProvider.NewInstanceFactory和其他用途ViewModelProvider.AndroidViewModelFactory,所以我检查了这两个类的源代码,发现实际上是覆盖函数ViewModelProvider.AndroidViewModelFactory的实现,这意味着两者都在做相同的事情,如果是,最好选择两种方法我们想要多个参数,但是为此我们必须重写以创建我们自己的工厂,就像这里所做的那样ViewModelProvider.NewInstanceFactorycreateViewModelProvider.NewInstanceFactory
现在来了第三个:
val myViewModel3 = ViewModelProvider(this).get(MyViewModel::class.java)
当我们的 ViewModel 中没有多个参数并且不想延迟加载对象时,这是 1 和 2 的简单形式。
注意:我强烈推荐方法4或5(两者都是相同的,但语法不同),因为这是最合适和最佳的编写方式,如果你没有多个参数,如果你有多个参数,你可以使用该方法6.答案中提到的通过执行ViewModelProvider.Factory。
| 归档时间: |
|
| 查看次数: |
14436 次 |
| 最近记录: |