Дождитесь завершения сопрограммы, чтобы обработать щелчок пользователя - PullRequest
0 голосов
/ 19 июня 2019

Я создаю систему «сеансов», где пользователь может запускать, завершать и просматривать свой сеанс.
Пользователь проходит первый фрагмент, чтобы создать свою сессию, а затем входит во фрагмент "в сессии".
Если он вернется в главное меню до завершения сеанса, я хочу, чтобы он сразу перешел к «в сеансе», не просматривая фрагмент «нового сеанса».

Все данные сеанса хранятся в локальной базе данных, и я использую сопрограммы Kotlin для извлечения данных из БД (см. Пример кода ниже)

Я впервые использую сопрограмму, и я признаю, что это немного нечетко для меня вся помощь приветствуется

Проблема в в том, что когда пользователь нажимает кнопку для навигации, сопрограмма завершает после проверки, чтобы увидеть, существует ли текущий сеанс, который приводит к проверке нулевого объекта или предыдущий сеанс текущего сеанса и, таким образом, перейдите к фрагменту «новый сеанс»

Мне нужен способ дождаться окончания сопрограммы, а затем обрабатывать нажатие кнопки

Весь код, написанный здесь, содержится внутри модели представления .
Вот так я настраиваю Задание / Область

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 вызывается из оператора if из фрагмента itlsef, когда пользователь нажимает кнопку навигации.
Если это правда, тогда перейдите к «InSession», иначе в «newSession»

Я видел несколько способов ожидания завершения сопрограммы, но ни один из них не соответствовал тому, как я его запускаю, и еще меньше есть решение, которое сработало для меня.

1 Ответ

0 голосов
/ 20 июня 2019

Не могли бы вы привести простой пример, не связанный с вашим кодом?Но тесно связана с проблемой:

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