Почему я получаю нулевое значение LiveData после использования async {} в Android Studio с Kotlin? - PullRequest
3 голосов
/ 07 августа 2020

Запрос Code A LiveData<List<MVoice>> с Room и отображать их в элементе управления RecyclerView, он работает хорошо.

Я знаю, что запрос LiveData с Room будет выполняться в фоновом потоке, поэтому val dd вернет null в коде B.

Я думаю, что val bb вернет правильный List<MVoice> в Code C, но на самом деле он вернет null, почему?

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()
}

Код 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 

1 Ответ

4 голосов
/ 07 августа 2020

Ваш код можно упростить, удалив async-await, и он будет работать так же.

binding.button.setOnClickListener {
    val aa = mHomeViewModel.listVoice().value // It will be null too.
}

Код внутри async { ... } не такой, как вы, вероятно, думаете, что он работает. Чтобы объяснить это:

  • LiveData.getValue() не является функцией приостановки . Следовательно, async { ... } возвращается немедленно.

  • LiveData.getValue() предназначен для получения текущего значения без ожидания следующего первого значения. По этой причине это не функция приостановки.

...