[英]ViewModelProviders.of(FragmentActivity).get(ViewModel::class.java) asking for activity instead of viewmodel in get() call
[英]View model initialization using “by viewModels()” vs “ViewModelProvider(this).get(ViewModel::class.java)” in android
我们可以使用初始化ViewModel
class
private val viewModel: CharactersViewModel by viewModels()
或者
viewModel = ViewModelProvider(this).get(CharactersViewModel::class.java)
Herer CharactersViewModel 是我们的 ViewModel class。 我的问题是什么时候使用哪个? 两者是否包含相同的目的? 我已阅读 ViewModel 的 android 官方文档。该文档by viewModels()
Kotlin property delegate说。 但遗憾的是没能看懂。 谁能帮我理解这一点?
两者都做同样的事情,但对第一个有区分优势。 Kotlin 属性委托使用了Lazy Initialization
的思想。 在Wikipedia上,您可以找到它的简要定义:
在计算机编程中,延迟初始化是延迟 object 的创建、值的计算或其他一些昂贵的过程,直到第一次需要它的策略。 它是一种惰性求值,专门指对象或其他资源的实例化。
因此,当您使用您提到的第一种方法时,您利用了惰性属性。 这意味着 ViewModel 实例仅在首次访问时创建。
以下面的代码为例:
class YourFragment : Fragment() {
private val viewModel: CharactersViewModel by viewModels()
// other codes ...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// doing some view initialization ...
viewModel.someLiveData.observe(viewLifecycleOwner) {
// ...
}
}
}
如果viewModel.someLiveData.observe(viewLifecycleOwner)
是第一次触摸viewModel
字段,它将在那里发生实例化。 (创建CharactersViewModel
实例)
因此,使用像视图 model 这样的对象的延迟初始化可以减少片段的启动影响,从而加快加载和显示其内容,而不是直接初始化它们。
这两个陈述是相等的。
Kotlin 关键字只是by
您节省了一些代码,为您节省了使用反射访问 VM 的痛苦,并且看起来更干净,如果您像我一样。
要么或应该为你做这项工作:)
要添加到已经提到的答案,
lateinit 修饰符告诉类型检查器 var 属性将在使用之前“通过魔法”初始化,因此不需要赋予可为空的类型。 它会阻止类型检查器帮助您正确初始化属性。 相反,初始化中的编程错误会在运行时稍后由异常报告。
它适用于 Kotlin 代码与传统 Java 框架接口时使用反射将值插入类型检查器和可见性修饰符后面的字段中。
如果可能的话,我们应该尽量避免在我们的代码中使用lateinit ,在这种情况下你应该使用
private val viewModel: CharactersViewModel by viewModels()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.