异步获取Android Kotlin中的URL

所以我试图编写一个非常简单的Android应用程序,当按钮被按下时从URL获取响应。 kotlin Android扩展已经被广告作为Java中必要的样板的替代品,所以我试了我的手。 这是我到目前为止所尝试的:

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) } } } 

这个间歇性的工作,但现在完全破碎。 没有响应按钮点击。 打印调试显示线程得到执行,但似乎挂在readText()调用。 我在这里做错了什么蠢事?

我想你正在寻找这样的事情

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

除非我错了,否则你的代码看起来就像在UI线程上阻塞,而不是等待响应第一次返回

我知道你的情况,这是因为你正在使用runBlocking ,尽管await不会阻塞线程,但它会暂停协程,并且由于当前协程没有完成, runBlocking线程将被阻塞等待它。

所以只需使用runBlocking launc(UI)而不是runBlocking来解决这个问题:

 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) } } }