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

sam*_*dy1 2 android android-lifecycle kotlin android-room android-livedata

我有一个ViewModel具有 type 属性的属性LiveData<UserData>,正在从 Room 数据库中读取。

其代码如下:

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

private val viewModel: UserDataViewModel by viewModels()
Run Code Online (Sandbox Code Playgroud)

UserData在该活动中,我需要获取按钮单击的值:

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

从理论上讲,除非用户在加载数据之前按下按钮,否则它永远不应该为空。

然而,正如代码所示,对的调用viewModel.userData.value始终为空,并且该let块永远不会执行。

但是,如果我在 中添加此语句onCreatelet单击处理程序中的块将根据需要执行

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

我的问题是:即使我没有对更改事件执行任何操作,为什么我需要调用观察函数才能获得有效响应LiveData::getValue

Epi*_*rce 6

我的问题是:即使我没有对更改事件执行任何操作,为什么我需要调用观察函数才能从 LiveData::getValue 获取有效响应?

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

  • 最终,如果您确实打算使用 LiveData 作为绑定表达式的一部分,那么生成的绑定将根据您提供给绑定的“lifecycleOwner”注册一个观察者。所以是的,那么你就会有一个积极的观察者,这将不再是一个问题。 (2认同)