Android: Как прочитать файл из Inte rnet с помощью сопрограмм? - PullRequest
0 голосов
/ 06 апреля 2020

Мне нужно прочитать файл, расположенный по определенному URL. Я создал такую ​​функцию:

private fun urlRead() {
    val url = URL(MY_URL)
    val stream = url.openStream()
    val v = stream.read()
}

И я вызываю эту функцию из onCreate. Но это вызывает исключение NetworkOnMainThreadException. Android требует, чтобы приложения работали с сетями из другого потока. Документация рекомендует использовать сопрограммы для простых задач многопоточности. Но я не могу найти хороший пример использования сопрограмм в Kotlin в Android.

Можете ли вы привести пример короткого кода с кодом выше с использованием сопрограмм?

Ответы [ 3 ]

2 голосов
/ 06 апреля 2020

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

private suspend fun urlRead() = withContext(Dispatchers.IO) {
    val url = URL(MY_URL)
    val stream = url.openStream()
    stream.read()
}

, затем вы называете это так

lifecycleScope.launch {
    val v = urlRead()
    // TODO; use v
}

См. это для справки.

1 голос
/ 06 апреля 2020

Ну, во-первых: будет проще, если вы используете API жизненного цикла: https://developer.android.com/jetpack/androidx/releases/lifecycle

Если вы делаете запрос из действия, вы можете использовать «жизненный цикл». Если вы делаете из viewModel, вы можете использовать viewModelScope

Поскольку запрос может занять некоторое время до завершения sh, вы не можете сделать это из основного потока. Вы должны использовать IO.

Так, например, если вы используете viewModel:

class MyViewModel(): ViewModel() {
//some code

fun urlRead() {
    viewModelScope.launch(Dispatchers.IO){
        //here you make the requests
    }
}

}

0 голосов
/ 06 апреля 2020

я считаю этот учебник сопрограмм довольно понятным и легко усваиваемым https://kotlinlang.org/docs/reference/coroutines-overview.html

пример краткого кода

 private fun urlRead() {
    GlobalScope.launch(Dispatchers.IO) {
        val url = URL(MY_URL)
        val stream = url.openStream()
        val v = stream.read()
    }
}

Dispatchers.IO означает резьбу на кронштейне код будет работать в фоновом потоке, подробнее об этом читайте https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html

...