[英]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.