因此,我正在尝试编写一个非常简单的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()调用上。我在这里做错什么蠢事吗?
最佳答案
我知道您的情况,这是因为您使用的是runBlocking
,尽管await
并未阻塞线程,但是它将暂停协程,并且由于当前协程尚未完成,因此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)
}
}
}