简体   繁体   English

等待协程完成处理用户点击

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

I'm making a system of "sessions" where the user can launch, finish and view his session. 我正在创建一个“会话”系统,用户可以在其中启动,完成和查看他的会话。
The user go through a first fragment to create his session and then go into a fragment "in session". 用户通过第一个片段创建他的会话,然后进入“会话中”片段。
If he return to the main menu before finishing his session, I want him to go directly to "in session" without going through the "new session" fragment. 如果他在完成会话之前返回主菜单,我希望他直接进入“会话中”而不通过“新会话”片段。

All session data are stored into a local database and I use Kotlin coroutines to fetch data from the db (see code example below) 所有会话数据都存储在本地数据库中,我使用Kotlin协程从db中获取数据(参见下面的代码示例)

It's my first time using coroutine, and I will admit it's a bit fuzzy for me, all the help is welcome 这是我第一次使用coroutine,我会承认它对我来说有点模糊,欢迎所有的帮助

The problem is that when the user press the bouton to navigate, the coroutine finish after the verification to see if there is a current session, that lead to verify a null object or the previous session of the current session, and so navigate to a the "new session" fragment 问题在于 ,当用户按下bouton进行导航时,协程会验证完成以查看是否存在当前会话,导致验证空对象或当前会话的上一个会话,因此导航到“新会议”片段

What I need is a way to wait for the coroutine to finish and then handle the button click 我需要的是一种等待协程完成然后处理按钮点击的方法

All the code wrote here is contain inside inside the viewModel . 这里写的所有代码都包含在viewModel里面
This is how I setup the Job/Scope 这就是我设置作业/范围的方法

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

And this is how I launch the coroutine: 这就是我发布协程的方式:

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

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

The verification is made inside this function 验证是在此功能内完成的

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

This last function "isSessionActive" is called from an if statement from the fragment itlsef, when the user press the navigation button. 当用户按下导航按钮时,最后一个函数“isSessionActive”从片段itlsef的if语句中调用。
If it's true then it navigate to "InSession", else in "newSession" 如果它是真的那么它导航到“InSession”,否则导航到“newSession”

I've seen multiple way of waiting for a coroutine to finish but none match the way I launch it, and even less have a solution that has worked for me. 我已经看到了等待协程完成的多种方式,但没有一种方式与我启动它的方式相匹配,甚至更少有一个对我有用的解决方案。

Would you allow me with a simple example unrelated to your code? 您是否允许我使用与您的代码无关的简单示例? But strongly related to the problem: 但与问题密切相关:

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

EDIT: 编辑:

Since you stated you are in the ViewModel , you don't need to return any value, you need to observe that changed value: 既然您声明自己在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
    }
        }
       }
     }
    }

And than in your fragment: 而不是你的片段:

//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