简体   繁体   中英

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. 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. 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.

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?

Why is it that you still have to take code off the main thread on Android even if a task is suspended

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.

So, specifically, in Kotlin you can write

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

with some suspend fun makeRestCall(url: String) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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