Android Kotlin协同路由不下载数据
我在Android项目中使用Kotlin corountines。我正在尝试下载一些数据并显示在文本视图中 下面是我的代码Android Kotlin协同路由不下载数据,android,kotlin,kotlinx.coroutines,Android,Kotlin,Kotlinx.coroutines,我在Android项目中使用Kotlin corountines。我正在尝试下载一些数据并显示在文本视图中 下面是我的代码 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_mai
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv.setOnClickListener {
downloadData()
}
}
private fun downloadData() {
runBlocking {
pb_activity_main.visibility = View.VISIBLE
var data = ""
async {
data = downloadDataBlocking()
}.await()
tv.text = data
pb_activity_main.visibility = View.GONE
}
}
private fun downloadDataBlocking(): String {
val client = OkHttpClient()
val request = Request.Builder().url("https://jsonplaceholder.typicode.com/posts").build()
val response = client.newCall(request).execute()
return response.body()?.string() ?: ""
}
}
但是数据没有被下载。我不知道为什么
我已将internet权限包括在清单中,url也在工作。尝试以下操作:
class MainActivity : AppCompatActivity(), CoroutineScope {
private val job = Job()
override val coroutineContext = Dispatchers.Main + job
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv.setOnClickListener {
downloadData()
}
}
private fun downloadData() {
launch {
pb_activity_main.visibility = View.VISIBLE
tv.text = withContext(Dispatchers.IO) { downloadDataBlocking() }
pb_activity_main.visibility = View.GONE
}
}
private fun downloadDataBlocking(): String {
val client = OkHttpClient()
val request = Request.Builder().url("https://jsonplaceholder.typicode.com/posts").build()
val response = client.newCall(request).execute()
return response.body()?.string() ?: ""
}
}
第一:您应该不要使用运行阻塞
单元外测试或其他特殊领域
不应从协同程序中使用。它的设计目的是将常规阻塞代码桥接到以挂起方式编写的库中,以便在主要函数和测试中使用
第二:
,这是一个生命周期有限的实体
这就是Activity
实现CoroutineScope
的原因。老实说,更好的地方是ViewModel
或Presenter
,但我在代码中没有看到任何内容
第三,在定义之后立即使用async
和wait
是毫无意义的。只需在上下文中使用。试试以下方法:
class MainActivity : AppCompatActivity(), CoroutineScope {
private val job = Job()
override val coroutineContext = Dispatchers.Main + job
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv.setOnClickListener {
downloadData()
}
}
private fun downloadData() {
launch {
pb_activity_main.visibility = View.VISIBLE
tv.text = withContext(Dispatchers.IO) { downloadDataBlocking() }
pb_activity_main.visibility = View.GONE
}
}
private fun downloadDataBlocking(): String {
val client = OkHttpClient()
val request = Request.Builder().url("https://jsonplaceholder.typicode.com/posts").build()
val response = client.newCall(request).execute()
return response.body()?.string() ?: ""
}
}
第一:您应该不要使用运行阻塞
单元外测试或其他特殊领域
不应从协同程序中使用。它的设计目的是将常规阻塞代码桥接到以挂起方式编写的库中,以便在主要函数和测试中使用
第二:
,这是一个生命周期有限的实体
这就是Activity
实现CoroutineScope
的原因。老实说,更好的地方是ViewModel
或Presenter
,但我在代码中没有看到任何内容
第三,在定义之后立即使用async
和wait
是毫无意义的。只需将与上下文一起使用即可。这不是协同程序的有效使用,您所做的只是运行阻塞代码。@Minn我无法通过在runBlocking中写入来访问协同路由的启动或异步方法。问题是您正在协同路由中调用阻塞i/O操作,而阻塞i/O操作又会阻止协同路由调度程序执行任何其他操作。这意味着您将有效地减慢在该调度器上运行的所有操作,从而使协同路由的使用变得不好。此外,您使用运行阻塞
并立即等待您的协同程序,因此这本质上只是一个正常的功能,没有任何并发性。@Minn那么如何在Android Project中访问启动和异步而不运行阻塞?这不是协同程序的有效使用,您所做的只是运行阻塞代码。@Minn我无法通过在runBlocking中写入来访问协同路由的启动或异步方法。问题是您正在协同路由中调用阻塞i/O操作,而阻塞i/O操作又会阻止协同路由调度程序执行任何其他操作。这意味着您将有效地减慢在该调度器上运行的所有操作,从而使协同路由的使用变得不好。此外,您还可以使用运行阻塞
并立即等待您的协同程序,因此这本质上只是一个正常的函数,没有任何并发性。@Minn那么如何在Android Project中访问启动和异步而不运行阻塞?请确保您还扩展了协同程序作用域并导入了启动function@Minn对不起,我的bad@AndreyIlyunin我不确定。我没有得到任何有用的日志它编译了吗?@AndreyIlyunin是的。应用程序一直显示进度条。我已经复制粘贴了你的代码。我已经包括了internet许可,请确保您也在扩展CoroutineScope并导入发布function@Minn对不起,我的bad@AndreyIlyunin我不确定。我没有得到任何有用的日志它编译了吗?@AndreyIlyunin是的。应用程序一直显示进度条。我已经复制粘贴了你的代码。我已经包括了互联网许可