我已将上下文切换为 Dispatcher.Main 以显示UI,但在runBlocking上获取了数据,但无法在 RecylerView
中显示
runBlocking {
var fruits = fetchFruitList()
withContext(Dispatchers.Main){
recyclerView.adapter = FruitAdapter(fruits);
}
}
我在做什么错,将数据从一个Dispatcher返回到另一个Dispatcher的适当方法是什么?
我尝试了另一种方法
GlobalScope.launch {
withContext(Dispatchers.IO){
var fruits = arrayOf("Grapes","Apple","Mango","TuttiFruit","PineApple",
"Pomegrante","Apple","Mango","TuttiFruit","PineApple",
"Pomegrante","Apple","Mango","TuttiFruit","PineApple").toList()
return@withContext
}
recyclerView.adapter = FruitAdapter(fruits)
}
,但以上面的方式I have to declare fruits as global
,而我不想让它全局运行。有没有一种方法可以将数据从一个“调度程序”队列返回到另一个
我必须从Api(IO操作)中获取数据并在RecyclerView(主线程操作)中显示该数据
答案 0 :(得分:2)
那是因为在获取数据之后必须切换上下文:
GlobalScope.launch(Dispatchers.IO){
var fruits = arrayOf("Grapes","Apple","Mango","TuttiFruit","PineApple",
"Pomegrante","Apple","Mango","TuttiFruit","PineApple",
"Pomegrante","Apple","Mango","TuttiFruit","PineApple").toList()
withContext(Dispatchers.MAIN){
recyclerView.adapter = FruitAdapter(fruits)
}
}
根据评论进行编辑:
对于runBlocking
,请查阅文档第一段。
运行一个新的协程并中断当前线程,直到 它的完成。协程不应该使用此功能。它 旨在将常规阻止代码桥接到 以悬挂样式编写,用于主要功能和 测试。
其次,您要求使用GlobalScope
。是的,如果您使用Android进行协同程序,则应避免这种情况。 Reasons here。
如何在Android活动/片段中启动协同程序?
首先,我建议在ViewModel
或Presenter
中使用,但是如果要在活动/片段中启动协程,则需要一种方法来控制和管理它的取消以避免内存泄漏。
解决方案是:
private val job: Job = Job()
//or Dispatchers.IO
private val fragmentScope = CoroutineScope(Dispatchers.MAIN + job)
//launch a coroutine later in Activity/Fragment
fragmentScope.launch{
//the default coroutine dispatcher would be the defined dispatcher above
}
override fun onDestroy(){
super.onDestroy()
fragmentScope.cancel()
}
关于您的问题:
我在做什么错,返回数据的适当方法是什么 从一个调度员到另一个调度员
如果要从其他上下文返回值,也可以尝试以下解决方案:
someScope.launch(Dispatchers.MAIN){
var data = withContext(Dispatchers.IO){
val someData = fetchSomeData()
return@withContext data
}
if(data.isAvailable()){ //for example
//runing on the main thread
}
}