android - 为什么我在带有 Kotlin 的 Android Studio 中使用 async{} 后会得到 LiveData 的 null 值?
问题描述
LiveData<List<MVoice>>
带有 Room的 Code A 查询并在RecyclerView
控件中显示它们,效果很好。
我知道使用 Room 查询 LiveData 将在后台线程中运行,因此val dd
将在代码 B 中返回 null。
我认为在代码 C 中val bb
会返回正确List<MVoice>
,但实际上它返回 null,为什么?
代码 A
binding.button.setOnClickListener {
mHomeViewModel.listVoice().observe(viewLifecycleOwner){ listMVoice->
adapter.submitList(listMVoice)
}
}
@Dao
interface DBVoiceDao{
@Query("SELECT * FROM voice_table ORDER BY createdDate desc")
fun listVoice():LiveData<List<MVoice>>
}
class DBVoiceRepository private constructor(private val mDBVoiceDao: DBVoiceDao){
fun listVoice()= mDBVoiceDao.listVoice()
}
class HomeViewModel(private val mDBVoiceRepository: DBVoiceRepository) : ViewModel() {
fun listVoice()= mDBVoiceRepository.listVoice()
}
代码 B
binding.button.setOnClickListener {
val dd=mHomeViewModel.listVoice().value //It return null
}
... //It's the same as Code A
代码 C
binding.button.setOnClickListener {
lifecycleScope.launch{
val aa=async { mHomeViewModel.listVoice() }
val bb=aa.await().value //It return null too
}
}
... //It's the same as Code A
解决方案
您的代码实际上可以通过删除来简化,async-await
并且它的工作方式相同。
binding.button.setOnClickListener {
val aa = mHomeViewModel.listVoice().value // It will be null too.
}
里面的代码async { ... }
不是你可能认为的那样工作。解释这一点;
LiveData.getValue()
不是暂停功能。因此,async { ... }
立即退货。LiveData.getValue()
旨在获取其当前值而不等待下一个第一个值。这就是为什么它不是暂停功能的原因。
推荐阅读
- java - POS 客户显示(基于 Web 的应用程序)
- javascript - 在 HTML 中,我如何构建一个文件选择器,它可以在不使用动作监听器的情况下更改显示的图像?
- spring - Spring 5.0.5 @Value 无法解析为正确的类型
- python - 使用 Boosting 树在 sklearn 中生成特征
- symfony4 - Symfony 4 使用 URL 检查数据库是否存在页面,否则 404
- postgresql - 将一列字符串与其他表中的列匹配
- objective-c - 从另一个项目复制类并删除 XCode 中的连接
- javascript - window[name] 相当于动态访问 const 和 let 声明
- android - 仅在我的生产环境中来自 Google API 的“401:无效凭据”
- javascript - Cloud Functions for Firebase onWrite 触发器:snapshot.val 不是函数