TransWikia.com

Как дождаться окончания корутины

Stack Overflow на русском Asked by Shkum on December 16, 2021

Я только начал изучать котлин и корутины, так что прошу сильно не ругаться за глупый вопрос.

Надо дождаться окончания выполнение кода в корутине и потом получить значение функции, выполненной в корутине и включить кнопку. Функция test() выполняется в корутине что бы не подвисала программа, пока выполняется цикл.

Есть такой код:

suspend fun test(): String {
    delay(5000) // типа долгий цикл
    return "трали-вали" // строка полкченная полсе выполнения цикла
}

fun onClick(view: View) {
    GlobalScope.launch {
        val result: String = withContext(Dispatchers.Default) {
            test()
            btnStart.isEnabled = true // не работает :(
        }
    }
    var strokaIsCikla = result // не работает :(
}

как дождаться окончания корутины и включить кнопку?

как дождаться окончание корутины и получить из нее значение функции в переменную ( result)?

Понимаю что вопросы совсем глупые, но сам дотумкать не могу.


Вообще код выглядит так:

private var flag = false

private fun test(): String {
    var s: Long = 0
    while (s < 100000 && flag) { //  долгий цикл, зависит от вводимых данных
        s += 1
    }
    return "$s" // строка полученная после выполнения цикла
}


fun btnStartClick(view: View) {
    btnStart.isEnabled=false
    flag = true
    println(test())
    btnStart.isEnabled = true
}


fun btnStopClick(view: View) {
    flag = false
}

но во время цикла прога как бы зависает и это выглядит не очень эстетично.
Я подумал что можно цикл вынести в корутину что избкжать подвисания.
Но возможно есть другой вариант. Хочется избежать подвисания программы во время выполнения цикла. Что бы, например, была возможность нажать btnStop и остановить цикл. Но в моем коде во время цикла все висит и в том числе все View.

One Answer

GlobalScope.launch нельзя так использовать, данный механизм предназначен для выполнения отложенных задач, то есть как только вы описали что должно происходить в блоке GlobalScope.launch далеко не факт что он будет выполняться сразу, если нужно чтобы корутина возвращала результат используйте GlobalScope.async, но как понял вам нужно чтобы чтобы после выполнения какой либо задачи кнопка стала доступной, можно попробовать так

fun btnStartClick(view: View) {
    btnStart.isEnabled = false
    GlobalScope.launch(Dispatchers.Main) {
        flag = true
        println(test())
        btnStart.isEnabled = true
    }
}

Dispatchers.Main - имеется ввиду что корутина будет выполняться в главном UI потоке, но не будет его блокировать.

Answered by noname on December 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP