首页 > 解决方案 > 为什么我在带有 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 

标签: androidandroid-room

解决方案


您的代码实际上可以通过删除来简化,async-await并且它的工作方式相同。

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

里面的代码async { ... }不是你可能认为的那样工作。解释这一点;

  • LiveData.getValue()不是暂停功能。因此,async { ... }立即退货。

  • LiveData.getValue()旨在获取其当前值而不等待下一个第一个值。这就是为什么它不是暂停功能的原因。


推荐阅读