异步执行任务时阻塞Android上的主线程

时间:2019-03-06 03:51:45

标签: android asynchronous coroutine kotlin-coroutines

我一直在努力理解Android上的多线程与异步编程之间的区别。主要是为什么需要将长时间运行的任务从主线程中删除,即使该任务是使用协程等异步完成的。

给出的解释对我来说很有意义,尽管长时间运行的任务可能是异步的,但仍然可以在UI线程上完成它。因此,即使异步代码没有阻塞,但重要的是工作,而不是阻塞。这似乎是有道理的。

但是,也许只是我不知道的语言的细微差别,但是像JavaScript这样无法将其委托给任何其他单独线程使用的单线程语言也可以异步工作,但是您可以长时间运行JavaScript中的所有任务都是异步函数,并且永远不会出现任何错误,这表明您在主线程上做的工作过多,并且看到UI性能受到影响。

为什么即使任务被挂起,仍然需要从Android的主线程中删除代码,而不是使用像javascript这样仅依赖一个线程的语言?

1 个答案:

答案 0 :(得分:1)

  

为什么即使任务被挂起,仍然需要从Android的主线程中删除代码

你不知道。唯一的规则是

  

从主线程的事件队列中获取的任何单个事件都不需要花费很长时间来处理。

其中“ long”可能是一毫秒或两秒以上的所有内容。

如果您在事件处理程序中执行阻止同步操作,则该操作将计入该事件处理程序的执行时间。

如果您在事件处理程序中执行非阻塞的异步操作,则该处理程序实际上会在启动该操作后立即完成,并确保稍后当该操作的结果出现在队列中时,还会有另一个事件准备好了。

这是合作式与抢占式多线程的本质:在前一种情况下,用户代码负责将整个任务分成几个轻量级事件,而在后一种情况下,无论代码在做什么,操作系统都将其强制执行。由于整个GUI必须在单个线程上运行,因此,抢先式多线程处理不是一种选择。

因此,特别是在Kotlin中,您可以编写

launch(Dispatchers.Main) {
    val user = makeRestCall("/users/$id")
    usernameText.text = user.name
}

带有一些suspend fun makeRestCall(url: String)

相关问题