繁体   English   中英

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

[英]Blocking the main thread on Android while doing task asynchronously

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

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

但是,也许只是我不知道的语言中的细微差别,但是像 JavaScript 这样的单线程语言不能将其工作委托给任何其他单独的线程,它也可以异步工作,但是您可以在 JavaScript 中执行长时间运行的任务异步函数,并且永远不会出现任何错误,表明您在主线程上做了太多工作并从中看到 UI 性能下降。

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

为什么即使任务挂起你仍然需要从Android的主线程中取出代码

你没有。 唯一的规则是

从主线程的事件队列中取出的任何单个事件都不应该花很长时间来处理。

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

如果您在事件处理程序中执行阻塞、同步操作,它将计入该事件处理程序执行的持续时间。

如果您在事件处理程序中执行非阻塞的异步操作,处理程序实际上会在启动操作后立即完成,确保稍后在操作结果准备好时将另一个事件放置在队列中。

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

所以,具体来说,在 Kotlin 中你可以写

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

有一些suspend fun makeRestCall(url: String)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM