如何在主线程上使用Kotlin协同程序await()

Ros*_*hak 10 android kotlin kotlin-coroutines

我刚刚开始学习Kotlin协同程序,并试图模拟一些长时间的API调用,并在UI上显示结果:

class MainActivity : AppCompatActivity() {
    fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")

    override
    fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.setContentView(R.layout.activity_main)
        val resultTV = findViewById(R.id.text) as TextView

        val a = async(CommonPool) {
            delay(1_000L)
            6
        }

        val b = async(CommonPool) {
            delay(1_000L)
            7
        }

        launch(< NEED UI thread here >) {
            val aVal = a.await()
            val bVal = b.await()
            resultTV.setText((aVal * bVal).toString())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白我怎么可能launchmain上下文中使用方法.

不幸的是,我无法找到任何关于为协同程序的官方教程提供某些特定线程的结果的信息.

pt2*_*121 10

编辑:

另请参阅Kotlin回购中的官方示例

你需要实现Continuation接口,它可以回调到Android UI线程和Coroutine上下文

例如(从这里)

private class AndroidContinuation<T>(val cont: Continuation<T>) : Continuation<T> by cont {
    override fun resume(value: T) {
        if (Looper.myLooper() == Looper.getMainLooper()) cont.resume(value)
        else Handler(Looper.getMainLooper()).post { cont.resume(value) }
    }
    override fun resumeWithException(exception: Throwable) {
        if (Looper.myLooper() == Looper.getMainLooper()) cont.resumeWithException(exception)
        else Handler(Looper.getMainLooper()).post { cont.resumeWithException(exception) }
    }
}

object Android : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
    override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> =
        AndroidContinuation(continuation)
}
Run Code Online (Sandbox Code Playgroud)

然后尝试:

launch(Android) {
    val aVal = a.await()
    val bVal = b.await()
    resultTV.setText((aVal * bVal).toString()) 
}
Run Code Online (Sandbox Code Playgroud)

更多信息:

https://medium.com/@macastiblancot/android-coroutines-getting-rid-of-runonuithread-and-callbacks-cleaner-thread-handling-and-more-234c0a9bd8eb#.r2buf5e6h


Rom*_*rov 9

您应该使用kotlinx.coroutines项目模块中的上下文替换< NEED UI thread here >您的代码.它的用法在使用协同程序的UI编程指南中进行了解释,其中有很多示例.UIkotlinx-coroutines-android