簡體   English   中英

等待協程完成處理用戶點擊

[英]Wait for coroutine to finish to handle user click

我正在創建一個“會話”系統,用戶可以在其中啟動,完成和查看他的會話。
用戶通過第一個片段創建他的會話,然后進入“會話中”片段。
如果他在完成會話之前返回主菜單,我希望他直接進入“會話中”而不通過“新會話”片段。

所有會話數據都存儲在本地數據庫中,我使用Kotlin協程從db中獲取數據(參見下面的代碼示例)

這是我第一次使用coroutine,我會承認它對我來說有點模糊,歡迎所有的幫助

問題在於 ,當用戶按下bouton進行導航時,協程會驗證完成以查看是否存在當前會話,導致驗證空對象或當前會話的上一個會話,因此導航到“新會議”片段

我需要的是一種等待協程完成然后處理按鈕點擊的方法

這里寫的所有代碼都包含在viewModel里面
這就是我設置作業/范圍的方法

private var viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)

這就是我發布協程的方式:

private fun initializeLastSession() {
    uiScope.launch {
    lastSession.value = getLastSessionFromDatabase()
    }
}

private suspend fun getLastSessionFromDatabase(): Session? {
    return withContext(Dispatchers.IO) {
        var session = database.getLastSession()
        session
    }
}

驗證是在此功能內完成的

fun isSessionActive(): Boolean {
//Simplified
    if (lastSession.value = null) {
        return false
    } else if (...) {
        return true
    } else {
        return false
    }

當用戶按下導航按鈕時,最后一個函數“isSessionActive”從片段itlsef的if語句中調用。
如果它是真的那么它導航到“InSession”,否則導航到“newSession”

我已經看到了等待協程完成的多種方式,但沒有一種方式與我啟動它的方式相匹配,甚至更少有一個對我有用的解決方案。

您是否允許我使用與您的代碼無關的簡單示例? 但與問題密切相關:

uiScope.launch{
 withContext(Dispatchers.IO){
  val dataFromDatabase = getSomeDataFromDatabase()
  if (dataFromDatabase.notEmpty()){ //or something
    withContext(Dispatchers.Main){
     //send data to fragment here :)
    }
   }
 }
}

編輯:

既然您聲明自己在ViewModel ,則不需要返回任何值,您需要觀察更改的值:

//on top of your ViewModel class: 

val yourVariableName: MutableLiveData<Boolean> = MutableLiveData()

//than in your method: 
    uiScope.launch{
     withContext(Dispatchers.IO){
      val dataFromDatabase = getSomeDataFromDatabase()
      if (dataFromDatabase.notEmpty()){ //or something
        withContext(Dispatchers.Main){
         if (lastSession.value = null) {
        yourVariableName.value = false
    } else if (...) {
        yourVariableName.value = true
    } else {
        yourVariableName.value = false
    }
        }
       }
     }
    }

而不是你的片段:

//after you have successfully instantiated the `ViewModel`: 
mViewModel.yourVariableName.observe(this , Observer{ valueYouAreObserving->
 // and here you have the value true ore false 
 Log.d("Tag", $valueYouAreObserving)
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM