Shk*_*kum 10 android coroutine kotlin kotlin-coroutines
我在下面有一些代码。延迟(3000)只是长循环(或循环)的替代。我期待循环完成后println(res)会打印“Some String”然后启用button。但在现实生活中会println(res)打印一个空字符串并button在我单击它时同时启用。我的问题是:如何等待协程结束,并且只有在协程运行println(res)和button.isEnabled = true.
private var res: String = ""
private suspend fun test(): String {
delay(3000) // delay - just replacement for long loop
return "Some String" // String received after loop
}
fun onClick(view: View) {
res = ""
button.isEnabled = false
GlobalScope.launch {
res = withContext(Dispatchers.Default) {
test()
}
}
println(res) // 1. trying to get string received after loop, but not working
button.isEnabled = true // 2. button must be enabled after loop in cycle, but it's not waiting till end of loop
}
Run Code Online (Sandbox Code Playgroud)
dan*_*ela 13
这里要理解的主要事情是协程中的代码默认是按顺序执行的。 即协程相对于“兄弟”代码异步执行,但默认情况下协程内的代码同步执行。
例如:
fun DoSometing () {
coroutineA {
doSomethingA1()
doSomethingA2()
}
some additional code
}
Run Code Online (Sandbox Code Playgroud)
Corroutine A 将执行与一些附加代码相关的异步操作, 但 doSometingA2 将在 doSomethingA1 完成后执行。
这意味着,在协程中,下一段代码将在前一段代码完成后执行。因此,无论您想在协程完成后执行什么,您只需将其放在协程的末尾并声明要执行它的上下文(withContext)。
当然,如果您在协程中启动另一段异步代码(如另一个协程),则例外。
编辑:如果您需要从协程更新 UI,您应该在主上下文中执行它,即您将拥有如下内容:
GlobalScope.launch (Dispatchers.IO) {
//do some background work
...
withContext (Dispatchers.Main) {
//update the UI
button.isEnabled=true
...
}
}
Run Code Online (Sandbox Code Playgroud)
你可以尝试这样的事情:
suspend fun saveInDb() {
val value = GlobalScope.async {
delay(1000)
println("thread running on [${Thread.currentThread().name}]")
10
}
println("value = ${value.await()} thread running on [${Thread.currentThread().name}]")
}
Run Code Online (Sandbox Code Playgroud)
await 将等待协程完成,然后运行它下面的代码
fun onClick(view: View) {
res = ""
button.isEnabled = false
GlobalScope.launch(Dispatchers.Main){ // launches coroutine in main thread
updateUi()
}
}
suspend fun updateUi(){
val value = GlobalScope.async { // creates worker thread
res = withContext(Dispatchers.Default) {
test()
}
}
println(value.await()) //waits for workerthread to finish
button.isEnabled = true //runs on ui thread as calling function is on Dispatchers.main
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19500 次 |
| 最近记录: |