为 runBlocking 提供 Dispatches.Main 挂起 Android 应用程序。为什么?

Ely*_*lye 9 android kotlin kotlin-coroutines

当我在 Android 中运行下面的代码时,它运行良好。

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        runBlocking {
            launch { 
                Log.d("Track", "main runBlocking pre       : ${Thread.currentThread().name}")
                delay(500)
                Log.d("Track", "main runBlocking post      : ${Thread.currentThread().name}")
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

它打印

Track: main runBlocking pre       : main
Track: main runBlocking post      : main
Run Code Online (Sandbox Code Playgroud)

但是,如果我将 Main 上下文提供给runBlocking,如下所示

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        runBlocking(Dispatchers.Main) { // Provide Dispatchers.Main
            launch { 
                Log.d("Track", "main runBlocking pre       : ${Thread.currentThread().name}")
                delay(500)
                Log.d("Track", "main runBlocking post      : ${Thread.currentThread().name}")
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

它挂起而不是运行它。

注:Dispatchers.Main是使用

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
Run Code Online (Sandbox Code Playgroud)

为什么挂了?

我认为是不提供Dispatchers.MainrunBlocking是有它的主线程,这是一样的,提供运行Dispatchers.Main。我理解错了吗?

注意: 我使用的库如下

    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.21"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
    testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
Run Code Online (Sandbox Code Playgroud)

Ten*_*r04 5

runBlocking的默认调度程序是一个自定义调度程序,它使用它被调用的线程来运行协程的延续。这就是为什么当您从runBlocking协程块内登录时,它会报告它在主线程上。

然而,这与Dispatchers.Main. Dispatchers.Main通过将代码块作为可运行的代码块发布到主处理程序来处理协程延续的字面上的运行是不同的。但是,该处理程序当前正在运行此onCreate方法,并且在onCreate返回之前无法处理其队列中的其他消息。但是runBlocking在它的子协程返回之前不会返回,所以onCreate永远不会返回。

runBlocking另一方面,默认调度程序甚至在返回之前直接在当前线程上运行延续。它甚至不知道处理程序。如果您使用默认调度程序Dispatchers.main从内部启动协程runBlocking,我认为您会遇到同样的问题。