Смысл области сопрограммы заключается в том, что она доступна в том месте, где вы обнаруживаете, что пользователь ушел от текущей активности, так что вы можете отменить ее в одном центральном месте и отменить все дочерние сопрограммы. Ваше изменение, которое просто создает локальную одноразовую область, так же плохо, как и использование GlobalScope
. Если ваш код находится внутри Activity или Fragment, то заставьте этот класс реализовать CoroutineScope by MainScope
, вы можете увидеть более подробный пример в документации из CoroutineScope
.
Что касается обработки за исключением того, что код должен выглядеть примерно так, как вы его разместили, просто обратите внимание на переключение контекстов. Область сопрограммы должна указывать Main
в качестве диспетчера, и вам следует переключиться на IO
только для блокирующего сетевого вызова, например:
basicViewInterface.showProgressBar()
scope.launch {
try {
val productsType = withContext(Dispatchers.IO) {
mobileApi.apiMobileProductTypeGetAllPost(params, 0, 50, "", "")
}
viewProductType.loadAllTypeProduct(productsType)
basicViewInterface.hideProgressBar()
} catch (e: Throwable) {
basicViewInterface.displayError("error")
}
}
Было бы еще лучше и чище, если вы нажмете на это withContext
в тело apiMobileProductTypeGetAllPost
, потому что это беспокойство, локализованное для него. Со стороны это должна быть просто еще одна приостановляемая функция, которую можно вызывать, не беспокоясь о таких низкоуровневых деталях, как то, блокирует ли данная реализация неблокирование.
Я заметил, что другие упоминают обработчик исключений сопрограммы, но я не рекомендую использовать его. Он работает только на верхнем уровне иерархии сопрограмм и его целью является отлов только тех исключений, которые не были должным образом обработаны в бизнес-коде из-за ошибки программирования. Это эквивалент Thread.uncaughtExceptionHandler
в Java.