android - ViewModel 对象属性未初始化?
问题描述
我有时会收到UninitializedPropertyAccessException
(来自分析)的错误,但在我使用它的过程中,该应用程序从未崩溃过。我认为在应用程序在后台删除并且进程被终止之后就会发生这种情况 - 但我无法重现此错误。
在我的活动中,我执行以下操作:
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.xxx)
... // doing other stuff
viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
viewModel.init(
...,
...,
...,))
setUpObservables()
}
我的MyViewModel
样子:
class MyViewModel : ViewModel() {
var lateinit car: String
fun init(
car: String,
...: String?,
...: Boolean
) {
if (isInitialized) {
return
}
this.car = car
...
isInitialized = true
}
稍后我尝试访问car
对象,如果它未初始化,则会出错。问题是——这怎么会发生?car
对象在什么时候被初始化MyViewModel
。任何想法如何重现这个?任何想法如何避免这种情况?
解决方案
好的,所以我在我的一个工作项目的 ViewModel 中添加了这样的代码。
lateinit var car: String
fun init(car: String) {
this.car = car
}
并调用:
viewModel.init("car")
Log.d("CAR_DEBUG",viewModel.car)
并在我的控制台中收到预期的输出: D/CAR_DEBUG: car。所以它可以工作,但可能会出现错误,具体取决于您的实现。
此外,这不是正确的方法,我建议使用 MutableLiveData 观察者模式,以确保不会由于屏幕旋转或活动/片段重新创建而发生任何意外行为。考虑到这一点,将您的代码更改为:
var carObservable: MutableLiveData<String> = MutableLiveData()
fun init(car: String) {
carObservable.value = car
}
在活动/片段中:
viewModel.carObservable.observe(this, Observer {
Log.d("CAR_DEBUG",it)
})
// doesnt matter where your viewModel.init this will still work
viewModel.init("car")
这样,即使您在观察调用之后调用 init 函数,您也可以确保仅在值更改时才通知您。这实际上是使用 ViewModels 的推荐方式(通过观察者模式的反应方式)。这样做可以确保即使您旋转屏幕或重新创建 Activity/Fragment,您的 car 变量也将可用。
推荐阅读
- ios - 集合视图 Diffable 数据源单元格消失且未正确调整大小?
- json - 如何使用 toJson() 和 fromJson() 方法将 Json 对象映射到飞镖中的 LinkedHashMap?
- python - 基于多个键对列进行排序
- reactjs - 在接口对象内添加新属性而不动态更改打字稿中的类
- twilio - 从 twilio 子帐户拨打电话(makeCall)
- javascript - 如何替换特定字符后的所有单词匹配但忽略javascript中的下划线?
- python - Bokeh OpenURL 不适用于 GCP JuypterLab 中的 HTML 输出文件
- pandas - Pandas 从键值对中提取值
- node.js - 如何在 WSL 中安装 React 时修复 ENOENT 错误
- flutter - 颤振:致命错误:回调查找失败!- 每当播放音频时