Obtener una URL en Android Kotlin de forma asíncrona

Así que estoy tratando de escribir una aplicación de Android muy simple que obtiene una respuesta de una URL cuando se presiona un button. Las extensiones de Kotlin para Android se han anunciado como un reemploop directo para la plantilla necesaria en Java, así que probé mi mano. Esto es lo que intenté hasta ahora:

package com.example.susemihl.myapplication import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.TextView import kotlinx.android.synthetic.main.activity_main.* import kotlinx.coroutines.experimental.CommonPool import kotlinx.coroutines.experimental.async import kotlinx.coroutines.experimental.runBlocking import java.net.URL suspend fun fetch_url(url: String): String { return URL(url).readText() } fun fetch_async(url: String, view: TextView) = runBlocking { val result = async(CommonPool) { fetch_url(url) } view.setText(result.await()) } class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mainTextView.setText("Hello there.") mainButton.setOnClickListener { mainButton.setText("Check again.") fetch_async("https://random-app.appspot.com/", mainTextView) } } } 

Esto funcionó intermitentemente, pero ahora está completamente roto. No hay respuesta al clic del button. La debugging de printing me muestra que el subprocess se ejecuta, pero parece bloquearse en la llamada readText (). ¿Algo estúpido que estoy haciendo mal aquí?

Creo que estás buscando algo como esto

 async { val result = URL("url").readText() uiThread { mainTextView.setText(result) } } 

A less que me equivoque, su código parece que bloquea en el subprocess de interfaz de usuario, no espere la respuesta a la primera devolución.

Conozco tu caso, es porque estás usando runBlocking , aunque await no bloquear el hilo, pero suspenderá la coroutine, y debido a que la corrutina actual no se completó aún, el hilo runBlocking se bloqueará esperando por él.

Entonces solo use launc(UI) lugar de runBlocking para resolver este problema:

 package com.example.susemihl.myapplication import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.TextView import kotlinx.android.synthetic.main.activity_main.* import kotlinx.coroutines.experimental.CommonPool import kotlinx.coroutines.experimental.android.UI import kotlinx.coroutines.experimental.async import kotlinx.coroutines.experimental.launch import java.net.URL fun fetch_url(url: String): String { return URL(url).readText() } fun fetch_async(url: String, view: TextView) = launch(UI) { val result = async(CommonPool) { fetch_url(url) } view.text = result.await() } class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mainTextView.text = "Hello there." mainButton.setOnClickListener { mainButton.text = "Check again." fetch_async("https://jacksgong.com", mainTextView) } } }