Блокировка основного потока на Android при выполнении задачи асинхронно - PullRequest
1 голос
/ 06 марта 2019

Я пытался понять разницу между многопоточностью и асинхронным программированием на Android. Главным образом, почему долго выполняемая задача должна быть удалена из основного потока, даже если эта задача выполняется асинхронно с чем-то вроде сопрограммы.

Это имеет смысл для меня, учитывая объяснение, что, хотя длительная задача может быть асинхронной, она все еще выполняется в потоке пользовательского интерфейса. Таким образом, даже несмотря на то, что асинхронный код не блокирует, важна не только работа, но и блокировка. Кажется, это имеет смысл.

Однако, возможно, это просто нюансы в языке, о котором я не знаю, но однопоточный язык, такой как JavaScript, который не может передавать свою работу любому другому отдельному потоку, работает также асинхронно, но вы можете долго работать задачи в JavaScript являются асинхронными функциями и никогда не получают никаких ошибок, указывающих на то, что вы выполняете слишком много работы с основным потоком и видите из-за этого потери производительности пользовательского интерфейса.

Почему вы все равно должны удалить код из основного потока на Android, даже если задача приостановлена, а не на языке, подобном javascript, который опирается только на один поток?

1 Ответ

1 голос
/ 06 марта 2019

Почему вы все равно должны удалить код из основного потока на Android, даже если задача приостановлена ​​

Вы не делаете. Единственное правило

Любое отдельное событие, взятое из очереди событий основного потока, не должно занять много времени.

где "long" - это, вероятно, все, что больше миллисекунды или двух.

Если вы выполняете блокирующую, синхронизирующую операцию в обработчике событий, она засчитывается во время выполнения этого обработчика событий.

Если вы выполняете неблокирующую, асинхронную операцию в обработчике событий, обработчик фактически завершает работу, как только инициирует операцию, гарантируя, что позднее в очередь будет добавлено другое событие, когда результат операции готов.

В этом суть кооперативной и вытесняющей многопоточности: в первом случае пользовательский код отвечает за разбиение всей задачи на несколько легких событий, тогда как во втором случае ОС применяет ее независимо от того, что делает код , Поскольку весь графический интерфейс пользователя должен выполняться в одном потоке, вытесняющая многопоточность не подходит.

Так, конкретно, в Kotlin вы можете написать

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

с некоторыми suspend fun makeRestCall(url: String).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...