Базовый вызов сопрограммы в библиотеке - PullRequest
0 голосов
/ 26 февраля 2019

Я просто читаю и изучаю сопрограммы в Котлине, которые можно использовать в небольшой библиотеке для развлечения / обучения.В документации вы можете сделать что-то вроде

GlobalScope.launch {

}

Так что в моем методе

fun myMethod() {
    GlobalScope.launch {
        // do some networking code
    }   
}

Лучше ли использовать GlobalScope для запуска сопрограммы для библиотеки?В документах написано:

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

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

Я также пытался

runBlocking {
    async {
        // do some networking code
    }
}

Думая, что runBlocking вводит новую область сопрограмм,но я думаю, что в этом случае он наследует область действия от своих родителей, которые являются основным потоком, поэтому я получаю исключение об отсутствии сети в основном потоке пользовательского интерфейса.

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

В зависимости от того, чего вы пытаетесь достичь, вы можете использовать различные шаблоны даже внутри библиотеки.

Если ваша функция должна немедленно вернуть после запуска некоторых сопрограмм, "лучшийпрактика "состоит в том, чтобы объявить вашу функцию как расширение CoroutineScope, таким образом, вам не нужно использовать глобальную область видимости:

fun CoroutineScope.launchesAndReturnsImmediately() {
    // launch can be called because we are extending CoroutineScope
    launch {
        // some work
    }
}

Как говорится, вы часто ненеобходимо немедленно вернуть в библиотеке, чтобы вы могли объявить свои функции suspend, что легче понять на стороне потребителя.Существует несколько вариантов:

  • выполнить некоторую работу в фоновом режиме, используя withContext для запуска в соответствующем пуле потоков, или вызвать другие функции приостановки
  • , использовать coroutineScope для запуска дочерних сопрограмми декомпозировать работу, но по-прежнему приостанавливать до тех пор, пока все дочерние сопрограммы не будут выполнены
0 голосов
/ 27 февраля 2019

Вы можете создать функцию приостановки, и это обеспечит, чтобы пользователь сам вызывал ее из сопрограммы.Если ваш метод использует withContext, вам не нужно беспокоиться о GlobalScope или настройке области действия.withContext просто сообщает сопрограмме, какой контекст использовать (для работы с сетью вам понадобится IO. И область действия теперь определяется тем, как пользователь ее запускает.

Способ, которым я бы сконструировал ваш методбудет:

suspend fun myMethod() = withContext(Dispatchers.IO) {
    // do some networking code
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...