NetworkOnMainThreadException с URL (). ReadText () в сопрограммах kotlin - PullRequest
0 голосов
/ 01 апреля 2019

Я работаю в Android Studio и использую сопрограммы kotlin для получения результатов из API.

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

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

Я пытался с Fuel.get (), и он работал нормально, но хотел бы использовать URL ().

var response = "";
val req = "url.com"
runBlocking { launch {
            response = URL(req).readText()
} }

Может кто-нибудь сказать мне, почему этот код не работает? Он генерирует исключение NetworkOnMainThreadException, но он заключен в сопрограмму.

Ответы [ 3 ]

0 голосов
/ 01 апреля 2019

Если вы просто хотите обработать результат URL(req).readText() в другом потоке, выполните следующие коды.

var response = "";
val req = "url.com"
runBlocking<Unit> { 
GlobalScope.launch {
    response = URL(req).readText()
    //here is another thread,handle response here
}
 //here is main thread, you can't get the result of URL(req).readText() because io operation need a long time .

}

Если вы обрабатываете результат в главном потоке, используйте класс Hanlder

0 голосов
/ 02 апреля 2019

Я исправил это.Закончилось использованием AsyncTask для чтения из URL и Handler для планирования обработки результатов.

var response = ""

@SuppressLint("StaticFieldLeak")
inner class Retriever : AsyncTask<String, String, String>() {
      override fun doInBackground(vararg args : String?): String {
            val urlRequest = args[0].toString()
            var urlResponse = "";

            //Try to extract url
            try {
                urlResponse = URL(urlRequest).readText()
                println("SUCCESS in Retrieve.")
            } catch (e : Exception) {
                println("EXCEPTION in Retrieve.")
                e.printStackTrace()
            }
            return urlResponse;
        }

        //Assigns value to response
        override fun onPostExecute(result: String?) {
            response = result.toString() //Result possibly void type
    }
}

override fun onCreate() {
    Retriever().execute("url.com")
    Handler().{/*Handle response here*/, 10000)
}
0 голосов
/ 01 апреля 2019

Попробуйте вот так

var response = "";
val req = "url.com"
runBlocking<Unit> { 
GlobalScope.launch {
    response = URL(req).readText()
}
    //Work with the response here
}

Вы можете просмотреть всю сопрограммную документацию здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...