Используя runBlocking
, вы блокируете главный поток до завершения сопрограммы.
Исключение NetworkOnMainThread
не вызывается, поскольку технически запрос выполняется в фоновом потоке, но, заставляя основной поток ждать, пока не завершится фоновый поток, это так же плохо!
Чтобы исправить это, вы можете launch
сопрограмму, и любой код, который зависит от сетевого запроса, может быть выполнен внутри сопрограммы. Таким образом, код может все еще выполняться в главном потоке, но он никогда не блокируется.
// put this scope in your activity or fragment so you can cancel it in onDestroy()
val scope = MainScope()
// launch coroutine within scope
scope.launch(Dispachers.Main) {
try {
val result = withContext(Dispachters.IO) {
// do blocking networking on IO thread
""
}
// now back on the main thread and we can use 'result'. But it never blocked!
} catch(e: Exception) {
}
}
Если вам не нужен результат и вы просто хотите запустить какой-то код в другом потоке, это можно упростить до:
GlobalScope.launch(Dispatchers.IO) {
try {
// code on io thread
} catch(e: Exception) {
}
}
Примечание: если вы используете переменные или методы из включающего класса, вы все равно должны использовать свою собственную область видимости, чтобы ее можно было со временем отменить.