首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么kotlin协同器可以在另一个线程上操作UI元素?

为什么kotlin协同器可以在另一个线程上操作UI元素?
EN

Stack Overflow用户
提问于 2019-04-25 12:41:03
回答 3查看 640关注 0票数 1

我正在尝试kotlinx.coroutines (版本: 1.2.0)。下面是一个简单的测试代码块:

代码语言:javascript
复制
GlobalScope.launch {
  Logger.i("${Thread.currentThread()}, ${Looper.myLooper() == Looper.getMainLooper()}")
  text_view.text = "test"
}

打印的日志是:

代码语言:javascript
复制
Thread[DefaultDispatcher-worker-2,5,main], false

如日志所示,我们不是在Android主线程上,即UI线程上。但是,在此工作线程上将文本设置为text_view并将"test“正确设置为text_view之后,上面的代码不会抛出异常。理由是什么呢?

更新1:

delay(10000L)之前添加setText()将导致异常,而更短的时间(比如在我的测试中测试冷启动的调试运行中的1000 L)不会导致异常,所以这似乎是一个安卓问题。但问题仍然存在,原因是什么?

更新2:

现在我意识到这种行为与安卓有关,而不是kotlinx.coroutines。在onCreate()中执行上述代码时,ViewRootImpl可能没有调用performTraversals()或初始化所有View。在这种情况下,用户界面操作之前的checkThread()也不会被调用。

EN

回答 3

Stack Overflow用户

发布于 2019-04-25 13:09:49

默认调度程序(在Dispatchers.Default中启动coroutines时使用)由GlobalScope表示,并使用共享后台线程池,因此launch(Dispatchers.Default) { ... }使用与GlobalScope.launch { ... }相同的调度程序。

因此,当没有参数使用launch { ... }时,它从正在启动的CoroutineScope继承上下文(以及因此也是dispatcher)。

在这种情况下,它继承主线程的上下文。

因此,除非我们定义了上下文& dispatcher,否则Coroutine将在主线程上工作,从DefaultDispatcher创建新的辅助线程(在我们的示例中是main )。

票数 0
EN

Stack Overflow用户

发布于 2019-04-25 13:30:22

跟科特林的合作毫无关系。

即使您不应该从非UI线程调用UI函数,但并不是每个Android函数实际上都检查您是否在UI线程上。TextView#setText()就是其中之一,您可以从后台线程调用它,而不会得到异常。

票数 0
EN

Stack Overflow用户

发布于 2021-04-12 14:14:47

代码语言:javascript
复制
 GlobalScope.launch(Dispatchers.Main) {
            mTvText?.text = "text" // exemple: set text in main thread
            ... // write also your code here
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55849540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档