使用 viewModelScope.launch 时如何获得 return 结果?

How can I get return result when I use viewModelScope.launch?

我希望得到一个 Int return 结果,代码 return mDBVoiceRepository.edit(aMVoice) 不起作用,我该如何解决?

代码A

@Dao
interface DBVoiceDao{
   @Update
   suspend fun edit(aMVoice: MVoice): Int
}


class DBVoiceRepository private constructor(private val mDBVoiceDao: DBVoiceDao){
    suspend fun edit(aMVoice: MVoice):Int{
        return mDBVoiceDao.edit(aMVoice)
    }
}


class HomeViewModel(private val mDBVoiceRepository: DBVoiceRepository) : ViewModel() {
 
    fun edit(aMVoice: MVoice):Int{
        viewModelScope.launch {
           return mDBVoiceRepository.edit(aMVoice)
        }
    }

}

新增内容1:

如果我将结果类型重新设计为 LiveData<Int>,有没有简单的方法?

代码B

@Dao
interface DBVoiceDao{
    @Update
    suspend fun edit(aMVoice: MVoice): LiveData<Int>
}


class DBVoiceRepository private constructor(private val mDBVoiceDao: DBVoiceDao){
    suspend fun edit(aMVoice: MVoice): LiveData<Int>{
        return mDBVoiceDao.edit(aMVoice)
    }
}


class HomeViewModel(private val mDBVoiceRepository: DBVoiceRepository) : ViewModel() {

    fun edit(aMVoice: MVoice):LiveData<Int>{
       //How can I do?
    }

}

新增内容2:

我运行你的代码在Fragment中,代码C可以得到正确的结果,而代码D不能得到正确的结果,为什么?

 //Code C
//Return correct ID
binding.button.setOnClickListener {
     val aMVoice = MVoice()
     var id=mHomeViewModel.edit(aMVoice)
     id.observe(viewLifecycleOwner){ rowId-> binding.button.text="ID is: "+ rowId.toString()}
}   

//Code D
//ID value return null
binding.button.setOnClickListener {
   lifecycleScope.launch{
       val aMVoice = MVoice()
       var id=mHomeViewModel.edit(aMVoice)
       binding.button.text="ID is: "+ id.value.toString()
   }
}

如果您无法访问流量,请使用实时数据

fun edit(aMVoice: MVoice):LiveData<Int>{
   val result = MutableLiveData<Int>()
    viewModelScope.launch {
      val data = mDBVoiceRepository.edit(aMVoice)
      result.value = data //or result.postValue(data)
    }
   return result
}

流版本看起来像

suspend fun edit(aMVoice: MVoice):Flow<Int>{
     return flow {
           val data = mDBVoiceRepository.edit(aMVoice)
           emit(data)
     }.flowOn(Dispatchers.IO)
}

您可以使用 lifecycleScope.launch{}[在您的 activity 或片段中 收集{} =14=]

编辑:

suspend fun edit(aMVoice: MVoice):LiveData<Int>{
   //here return the repository version of the edit
   mDBVoiceRepository.edit(aMVoice)
}

现在上面的设置可以直接在activity或者lifecycleScope.launch里面的fragment中观察到{}

或者您可以稍微修改一下以删除暂停合约。

 fun edit(aMVoice: MVoice):LiveData<Int>{
     val result = MutableLiveData<Int>()
      viewModelScope.launch(Dispatchers.IO) {
       //here return the repository version of the edit
       result.value = mDBVoiceRepository.edit(aMVoice).value
      }
     return result
   }

并直接在片段或 activity 中观察这一点,没有协程范围。如果需要,相应地调整微小的变化。