Когда и как вызвать функцию приостановки из Android Activity? - PullRequest
0 голосов
/ 06 июля 2019

У меня есть suspend функция, которая вызывает POST-запрос к серверу. Я хочу настроить текст в упражнении для отображения информации, полученной с сервера.

suspend fun retrieveInfo():String 

Я пытался звонить внутри onCreate, onResume, но вылетал во время выполнения.

runBlocking { 
    retrieveInfo()
}
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.augmentedimage/com.google.AugmentedImageActivity}: android.os.NetworkOnMainThreadException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3086)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3229)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)

Куда я положу эти приостановленные вызовы (в какой части жизненного цикла действия)? Должен ли я использовать что-то, кроме runBlocking?

1 Ответ

1 голос
/ 06 июля 2019

По умолчанию runBlocking запускает код приостановки block в потоке runBlocking.

Таким образом, если вы вызвали runBlocking из обратного вызова Activity, ваш приостановленный блок будет выполнен в главном потоке, из которого вы не можете получить доступ к сети (запросить сервер).

Вам нужно переключить диспетчера в блоке сопрограмм для этого вызова. Простейшим исправлением для вашего кода было бы перенести выполнение на Dispatchers.IO.

runBlocking {
    withContext(Dispatchers.IO) {
        retrieveInfo()
    }
}

При этом я предлагаю две вещи (не связанные непосредственно с вашим вопросом):

  1. Чтение Coroutines on Android (эта часть и следующие)

2. Не используйте runBlocking для вашего случая, но определите правильный job и используйте job.launch{}

...