简体   繁体   English

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

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

I've been struggling to understand the difference between multi threading v asynchronous programming on Android.我一直在努力理解 Android 上多线程与异步编程之间的区别。 Mainly, why a long running task needs to be taken off the main thread, even if that task is done asynchronously with something like a coroutine.主要是为什么需要从主线程中删除长时间运行的任务,即使该任务是使用协程等异步完成的。

It makes sense to me given the explanation that even though a long running task may be asynchronous, that it's still work being done on the UI thread.考虑到即使长时间运行的任务可能是异步的,它仍然在 UI 线程上完成工作,这对我来说是有意义的。 So even though the asynchronous code isn't blocking, it's the work that matters and not so much that it's blocking.因此,即使异步代码没有阻塞,重要的是工作而不是阻塞。 That seems to make sense.这似乎有道理。

However, maybe just nuances in the language that I'm not aware of, but a single threaded language like JavaScript that can't delegate it's work over to any other separate thread works asynchronously as well, but you can have long running tasks in JavaScript a asynchronous functions and never get any errors signifying that you're doing too much work on the main thread and see UI performance hits from it.但是,也许只是我不知道的语言中的细微差别,但是像 JavaScript 这样的单线程语言不能将其工作委托给任何其他单独的线程,它也可以异步工作,但是您可以在 JavaScript 中执行长时间运行的任务异步函数,并且永远不会出现任何错误,表明您在主线程上做了太多工作并从中看到 UI 性能下降。

Why is it that you still have to take code off the main thread on Android even if a task is suspended, and not in a language like javascript that only relies on one thread?为什么即使任务被挂起,你仍然需要从 Android 的主线程中删除代码,而不是像 javascript 这样只依赖一个线程的语言?

Why is it that you still have to take code off the main thread on Android even if a task is suspended为什么即使任务挂起你仍然需要从Android的主线程中取出代码

You don't.你没有。 The only rule is唯一的规则是

Any single event taken from the main thread's event queue shouldn't take long to handle.从主线程的事件队列中取出的任何单个事件都不应该花很长时间来处理。

where "long" is probably everything above a millisecond or two.其中“长”可能是一两毫秒以上的所有内容。

If you perform a blocking, sync operation in an event handler, it counts towards the duration of that event handler's execution.如果您在事件处理程序中执行阻塞、同步操作,它将计入该事件处理程序执行的持续时间。

If you perform a non-blocking, async operation in an event handler, the handler actually completes as soon as it initiates the operation, making sure there will be another event placed on the queue later on, when the result of the operation is ready.如果您在事件处理程序中执行非阻塞的异步操作,处理程序实际上会在启动操作后立即完成,确保稍后在操作结果准备好时将另一个事件放置在队列中。

That's the essence of cooperative vs. preemptive multithreading: in the former case, the user code is responsible to chop the total task into several lightweight events, while in the latter case, the OS enforces it regardless of what the code is doing.这就是合作与抢占式多线程的本质:在前一种情况下,用户代码负责将整个任务分成几个轻量级事件,而在后一种情况下,无论代码在做什么,操作系统都会强制执行。 Since the entire GUI must be run on a single thread, preemptive multithreading is not an option.由于整个 GUI 必须在单个线程上运行,抢占式多线程不是一个选项。

So, specifically, in Kotlin you can write所以,具体来说,在 Kotlin 中你可以写

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

with some suspend fun makeRestCall(url: String) .有一些suspend fun makeRestCall(url: String)

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

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