How to wait for the end of the coroutine

I just started learning kotlin and korutin, so please do not swear too much for a stupid question.

It is necessary to wait for the end of the code execution in the coroutine and then get the value of the function executed in the coroutine and turn on the button. The test() function is executed in the coroutine so that the program does not hang while the loop is running.

There is such a code:

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 // не работает :(
}

How do I wait for the end of the coroutine and turn on the button?

How to wait for the end of the coroutine and get the function value from it to a variable (result)?

I understand that the questions are quite stupid, but I can't think about it myself.


In general, the code looks like this:

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
}

But during the cycle, the prog seems to hang and it does not look very aesthetically pleasing. I thought that it is possible to take out the cycle in korutina that izbkzhat suspensions. But perhaps there is another option. I want to avoid hanging the program during the execution of the loop. So that, for example, it would be possible to press btnStop and stop cycle. But in my code, everything hangs during the loop, including all the Views.

Author: Shkum, 2019-12-25

1 answers

GlobalScope. launch can not be used like this, this mechanism is designed to perform deferred tasks, that is, once you have described what should happen in the GlobalScope.launch block, it is far from the fact that it will be executed immediately, if you need the coroutine to return the result, use GlobalScope. async, but as I understand you need to make the button available after completing any task, you can try this

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

Dispatchers.Main - it means that the coroutine it will be executed in the main UI thread, but it will not block it.

 0
Author: noname, 2020-03-18 09:45:58