Ben*_*654 6 android kotlin kotlin-coroutines
我试图在0.30.0中使用最新的协同程序,并且无法弄清楚如何使用新的作用域.在原始的协同程序中,我可以使用UI或CommonPool设置上下文,一切正常.
现在我正在尝试在从房间数据库中读取时在我的ViewModel中使用GlobalScope,然后我想将返回的值赋给我的LiveData对象.
我尝试设置LiveData值时收到以下错误
java.lang.IllegalStateException:无法在后台线程上调用setValue
fun getContact() {
GlobalScope.launch {
val contact = contacts.getContact() // suspended function
withContext(Dispatchers.Default) { phoneContact.value = contact }
}
}
Run Code Online (Sandbox Code Playgroud)
我只看到调度员的默认,无限和IO,而且没有一个工作,我无法弄清楚我做错了什么?我对主线程的选择在哪里?
Mar*_*nik 25
您通过添加依赖项解决了您的直接问题,但是让我添加一个关于您的使用情况的说明GlobalScope.
使用GlobalScopein生产代码是反模式.这是出于类似的原因,例如
runBlocking,使快速实验变得容易.由于应用程序组件的生命周期复杂,您应该特别避免在Android上使用它.
如果您从Android事件处理程序启动协程,则应使用当前的Activity作为其协程范围.这将确保您的协程在活动被销毁时被取消.没有它,协程将继续,指的是现在已经死亡的活动.
这是一个根据文档CoroutineScope改编的示例,它显示了如何将您的活动用作协程范围:
class MyActivity : AppCompatActivity(), CoroutineScope {
// Sets up the default dispatcher and the root job that we can use to centrally
// cancel all coroutines. We use SupervisorJob to avoid spreading the failure
// of one coroutine to all others.
override val coroutineContext: CoroutineContext =
Dispatchers.Main + SupervisorJob()
override fun onDestroy() {
super.onDestroy()
coroutineContext[Job]!!.cancel()
}
// this.launch picks up coroutineContext for its context:
fun loadDataFromUI() = this.launch {
// Switch to the IO dispatcher to perform blocking IO:
val ioData = withContext(Dispatchers.IO) {
// blocking I/O operations
}
draw(ioData) // use the data from IO to update UI in the main thread
}
}
Run Code Online (Sandbox Code Playgroud)
如果您正在使用a ViewModel,请将其用作范围并从中取消主作业onClear.
如果您正在从后台工作中完成工作,请使用您的JobService实现作为范围和用途onStartJob以及onStopJob我们使用onCreate和onDestroy上面的方式.
我在gradle文件中缺少了coroutines的Android部分
实现"org.jetbrains.kotlinx:kotlinx-coroutines-android:0.30.0"
有一次,Dispatchers.Main出现了
| 归档时间: |
|
| 查看次数: |
6926 次 |
| 最近记录: |