跳至主要內容

切换至 UI 线程

guodongAndroid大约 2 分钟

切换至 UI 线程

从你目前看到的情况来看,协程都是比较简单的,它们的大部分功能都内置在语言本身中。切换至 UI 线程也并不复杂,可以以 UI dispatcher 作为其线程上下文来启动一个新的协程。

由于我们讨论的是具有可见用户界面的应用程序,因此您可以发布到 Android、Swing 和 JavaFx 应用程序的主线程。您可以通过以下方式使用 Dispatchers.Main 作为上下文:

GlobalScope.launch(Dispatchers.Main) { ... }

注意,上面的代码还不能运行。您需要设置以下依赖项之一:

implementation "org.jetbrains.kotlinx:kotlinx-coroutinesandroid:..."
implementation "org.jetbrains.kotlinx:kotlinx-coroutinesswing:..."
implementation "org.jetbrains.kotlinx:kotlinx-coroutinesjavafx:..."

否则,程序将会抛出以下异常:

Exception in thread "DefaultDispatcher-worker-3" java.lang.IllegalStateException: Module with the Main dispatcher is missing. Add dependency providing the Main dispatcher, e.g. ’kotlinx-coroutines-android’

您可以通过一个简单的 Swing 示例来尝试上述代码。首先,您需要将此依赖项添加到 build.gradle:

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-swing:$kotlin_coroutines_version"

通过点击 Gradle 选项卡右上方的 Sync 按钮来同步并重新加载 Gradle 项目。然后,您可以将 main 函数替换为:

fun main() {
    GlobalScope.launch {
        val bgThreadName = Thread.currentThread().name
        println("I’m Job 1 in thread $bgThreadName")
        delay(200)
        GlobalScope.launch(Dispatchers.Main) {
            val uiThreadName = Thread.currentThread().name
            println("I’m Job 2 in thread $uiThreadName")
        }
    }
    Thread.sleep(1000)
}

同时并导入 Dispatchers 。外部协程打印执行它的线程的名称。经过短暂的延迟后,您使用 Dispatchers.Main 作为 CoroutineContext 启动另一个协程。这是您与主线程交互方式的其中一种。

运行上述代码,可能得到以下输出结果:

I’m Job 1 in thread DefaultDispatcher-worker-1
I’m Job 2 in thread AWT-EventQueue-0

第一个 Job 由工作线程在后台执行。第二个由 Swing 中的主线程执行。很简单吧?

要查看本章中的示例,请使用 IntelliJ 打开本章的最终项目并导航到 getting-started-with-coroutines/projects/final 文件夹,选择getting_started_with_coroutines 项目。