我有这样的代码:

override fun onResume() {
        super.onResume()
        lifecycleScope.launch(Dispatchers.Main) {
            println(1)
            delay(3000)
            println(2)
        }
        println(3)
    }

可以进行任何阻止操作,而不是delay个.

Dispatchers.Main没有线程池吗?这条流应该被阻止.为什么输出是这样的:3 -> 1 -> 2.而不是1 -> 2 -> 3?默认情况下,viewModelscope也适用于Dispatchers.Main

帮我弄清楚

推荐答案

如果您将代码更改为:

override fun onResume() {
        super.onResume()
        lifecycleScope.launch(Dispatchers.Main.immediate) {
            println(1)
            delay(3000)
            println(2)
        }
        println(3)
    }

...那么你就会更接近你的预期输出--至少在Kotlin/JS,你会得到1,然后是3,然后是2.

Dispatchers.Main.immediateDispatchers.Main之间的差异与Activity上的runOnUiThread()View上的post()之间的差异非常相似.这两个方法都采用Runnable并在主应用程序线程上运行该Runnable.但是,主应用程序线程主要工作是执行发送到工作队列的工作.

  • post()Runnable放在该队列中,并立即返回

  • runOnUiThread()查看我们的代码是否在主应用程序线程上执行right now,如果是,则runOnUiThread()立即运行Runnable-如果在后台线程上进行runOnUiThread()调用,则它的行为类似于post()

Dispatchers.Main会将协程放在工作队列中.那个协程要到一段时间以后才会运行.由于onResume()是在主应用程序线程上调用的,并且协程将在稍后运行,因此println(3)首先执行.

Dispatchers.Main.immediate表示"如果我们的代码在主应用程序线程上执行,则立即运行协程",这与runOnUiThread()非常相似.由于onResume()是在主应用程序线程上调用的,因此至少println(1)会在println(3)之前被调用.

UPDATE: 2023-09-22:Dispatchers.MainDispatchers.Main.immediate的实际实现是特定于平台的,这可能会影响delay()的处理方式.在Kotlin/JS上(可能在基于Ian Lake's comment的Kotlin/JVM中),delay()将调度协程的其余部分稍后运行并释放当前线程.这允许主应用程序线程在launch()调用之后继续处理,因此println(3)发生了,println(2)发生在3秒标记处.您可能希望在其他Kotlin多平台目标中测试该行为,以确保它在那里同样有效.

Android相关问答推荐

在画布上画直线

将动作传递给嵌套的可组合物

将DiffUtils用于Android上的Recrecerview适配器

Modifer.Align()不适用于行/列/框中的文本.未解决的作用域实例错误

页面更改时不显示 cogo toast 消息

Android 14预测性背部手势-闪烁的白色背景色

Kotlin - 在继续之前如何等待这个协程完成?

Android Compose - 为什么 Canvas 中的drawText在底部被切断而不是在顶部?

Android Studio 在 list 文件中已经声明了活动类,但仍出现无法找到明确的活动类的错误

当父布局的背景为浅色时,Android ProgressBar 背景 colored颜色 变为灰色

在 compose 中做可变状态堆栈

ArrayList 上的 Android intent.getParcelableArrayListExtra 引发 Nullpointer 异常

[Android][Room] 将密封类存储到 Room 数据库中

在 jetpack compose 中交替使用 View.INVISIBLE

react 从输入中找到路径'lib/arm64-v8a/libfbjni.so'的本机2个文件

如何在jetpack compose中创建水印文字效果

Android Jetpack Compose - 找不到 R.drawable?

在 Compose 中使用 DeepLink 会导致无法向后导航

如何使用 Glide 将图像下载到设备内部存储

Xamarin 获取动态 ListView DataTemplate 中的按钮单击事件数据