GlobalScope
связывает жизненный цикл сопрограммы с жизненным циклом самого приложения . Это означает, что Coroutine, запущенный из этой области, будет продолжать жить до тех пор, пока не произойдет одно из двух действий
- Coroutine завершит свою работу.
- Само приложение уничтожено.
Использование asyn c или запуск на экземпляре GlobalScope крайне не рекомендуется.
Не указан Dispatcher.MAIN или Dispatchers.IO. Это правильный способ сделать это?
Да, а почему бы и нет? Если работа внутри сопрограммы не связана с UI или IO go для нее.
Должен ли я указывать диспетчер только тогда, когда я точно знаю, что мне нужна конкретная c область действия?
Чтобы ответить на этот вопрос, давайте сначала посмотрим определение launch
из документов
fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit ): Job (source)
Dispatcher
, о котором мы говорим, является своего рода CoroutineContext
. Как вы можете видеть из определения, если CoroutineContext
не упоминается (что означает, что мы не упомянули также и Dispatcher
), то по умолчанию установлено значение EmptyCoroutineContext
, которое внутренне использует Dispatchers.Default, и именно об этом говорят документы it,
CoroutineDispatcher по умолчанию, который используется всеми стандартными сборщиками, такими как launch, asyn c, et c, если в их контексте не указан ни диспетчер, ни какой-либо другой ContinuationInterceptor.
Он поддерживается общим пулом потоков в JVM. По умолчанию максимальное количество потоков, используемых этим диспетчером, равно количеству ядер ЦП, но не менее двух.
Так что даже если вы забудете упомянуть Dispatcher, планировщик выберет любое Произведите случайную доступную нить из пула и передайте ей сопрограмму. Но следите за тем, чтобы не начинать какую-либо работу, связанную с UI
, без упоминания Диспетчера.