为什么 LiveData.getValue return null 除非调用了 observe ?

Why does LiveData.getValue return null unless observe has been called?

我有一个 ViewModel,它有一个 属性 类型 LiveData<UserData>,正在从 Room 数据库中读取。

其代码如下:

class UserDataViewModel(application: Application) : AndroidViewModel(application) {

    private val userDataDao: UserDataDao = AppDatabase.getInstance(application).dao()
    val userData: LiveData<UserData?> = userDataDao.getUserData()

}

在关联的 activity 中,我获得了对视图模型的引用:

private val viewModel: UserDataViewModel by viewModels()

在 activity 中,我需要在单击按钮时获取 UserData 的值:

private fun handleClick(view: View) {
    viewModel.userData.value?.let {
        // do stuff if the userData is present
    }
}

现在理论上,除非用户在数据加载之前按下按钮,否则这永远不应该为 null。

但是,就代码而言,对 viewModel.userData.value 的调用始终为空,并且 let 块永远不会执行。

但是,如果我在 onCreate 中添加此语句,单击处理程序中的 let 块将按需要执行 :

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    viewModel.userData.observe(this, Observer {
        // do nothing
    })
}

我的问题是:为什么我需要调用 observe 函数,即使我对更改事件什么都不做,以从 LiveData::getValue 获得有效响应?

您无需调用 observe() 即可让 LiveData 放弃 null 以外的值。 LiveData 总是包含并最初产生 null 直到某些东西设置它的值。如果您不想要此初始空值,则应立即将其设置为其他值,然后再使 LiveData 可用于任何其他组件。如果你想知道它什么时候第一次包含一个非空值,你将需要使用观察者。

My question is: why do I need to call the observe function, even if I'm doing nothing with a change event, to get valid responses from LiveData::getValue?

因为从 Room DAO 返回的 ComputableLiveData 仅在 LiveData 至少有一个活动观察者(在 LiveData.onActive() 内)时才执行查询。然后它在不同的线程上异步运行,在未来的某个时候它会发布到 LiveData 中。