kik*_*ike 5 kotlin android-livedata kotlin-coroutines
我正在尝试从协程触发LiveData更新:
object AddressList: MutableLiveData<List<Address>>()
fun getAddressesLiveData(): LiveData<List<Address>> {
AddressList.value = listOf()
GlobalScope.launch {
AddressList.value = getAddressList()
}
return AddressList
}
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误:
IllegalStateException:无法在后台线程上调用setValue
有没有办法使它与协程一起工作?
pde*_*d59 18
您可以执行以下操作之一:
object AddressList: MutableLiveData<List<Address>>()
fun getAddressesLiveData(): LiveData<List<Address>> {
AddressList.value = listOf()
GlobalScope.launch {
AddressList.postValue(getAddressList())
}
return AddressList
}
Run Code Online (Sandbox Code Playgroud)
或者
fun getAddressesLiveData(): LiveData<List<Address>> {
AddressList.value = listOf()
GlobalScope.launch {
val adresses = getAddressList()
withContext(Dispatchers.Main) {
AddressList.value = adresses
}
}
return AddressList
}
Run Code Online (Sandbox Code Playgroud)
尽管其他人指出,在这种情况下,库提供了自己的方法来将操作发布到主线程,但协程提供了一种通用的解决方案,无论给定库的功能如何,该解决方案都可以工作。
第一步是停止使用GlobalScope
后台作业,这样做会导致泄漏,您的活动、计划作业或您从中调用它的任何工作单元可能会被破坏,但您的作业将在后台继续,甚至将其结果提交给主线程。以下是官方文档的GlobalScope
说明:
应用程序代码通常应使用应用程序定义的 CoroutineScope,强烈建议不要在 GlobalScope 实例上使用 async 或 launch。
您应该定义自己的协程范围,并且其coroutineContext
属性应包含Dispatchers.Main
为调度程序。此外,在函数调用中启动作业并返回LiveData
(这基本上是另一种Future
)的整个模式并不是使用协程的最方便的方法。相反你应该有
suspend fun getAddresses() = withContext(Dispatchers.Default) { getAddressList() }
Run Code Online (Sandbox Code Playgroud)
在调用站点,您应该有launch
一个协程,在其中您现在getAddresses()
可以像阻塞方法一样自由调用,并直接获取地址作为返回值。
我刚刚发现使用withContext(Dispatchers.Main){}
以下方法是可能的:
object AddressList: MutableLiveData<List<Address>>()
fun getAddressesLiveData(): LiveData<List<Address>> {
GlobalScope.launch {
withContext(Dispatchers.Main){ AddressList.value = getAddressList() }
}
return AddressList
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3851 次 |
最近记录: |