The Code A query LiveData<List<MVoice>> with Room and display them in RecyclerView control, it works well.
I know that query LiveData with Room will be run in a background thread, so val dd will return null in Code B.
I think val bb will return correct List<MVoice> in Code C, but in fact, it return null, why ?
Code 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()
}
Code B
binding.button.setOnClickListener {
val dd=mHomeViewModel.listVoice().value //It return null
}
... //It's the same as Code A
Code 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
Your code can actually be simplified by removing async-await and it will work the same.
binding.button.setOnClickListener {
val aa = mHomeViewModel.listVoice().value // It will be null too.
}
The code inside async { ... } is not how you probably think it works. To explain this;
LiveData.getValue() is not a suspending function. Hence, the async { ... } returns immediately.
LiveData.getValue() is intended to get its current value without waiting for next first value. This is the reason why it's not a suspending function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With