【发布时间】:2020-07-02 08:00:28
【问题描述】:
我正在运行此代码,因为 addListenerForSingleEvent 是一个长时间运行的操作:
CoroutineScope(IO).launch {
userRef.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()) {
withContext(Main) {
toggleLoading()
val intent = Intent(this@LogInActivity, MainActivity::class.java)
startActivity(intent)
finish()
}
} else{
withContext(Main) {
var addUsernameIntent = Intent(this@LogInActivity,
AddUsernameActivity::class.java)
startActivityForResult(addUsernameIntent, CHOOSE_USERNAME_REQUEST)
}
}
}
})
}
我在写 withContext(Main) 的地方收到一个错误,上面写着:
只能在协程体内调用挂起函数
但是我有一个协程体对吗?在我只有Thread(runnable {..}) 而不是协程之前,但我读到我不应该在除主线程之外的任何其他线程内执行意图,所以我改为协程。
【问题讨论】:
-
首先,实际上你根本没有使用 IO 协程!您只是在其中向
userRef添加了一个侦听器,这与 IO 无关。userRef背后的实现定义了如何调用该函数和执行任务。其次,您在onDataChange中调用withContext,所以它不在一个宫廷体中。 -
我真正想做的就是在单独的线程上运行运行监听器,我该怎么做? @MohammadOmidvar
-
首先,检查当前是否为真(大多数监听器在主线程中调用)。其次,您可以使用传统方式:
Handler(Looper.getMainLooper()).post()或runOnUiThread或者如果您想要协程(基于上述方法),您可以使用@commander-tvis 所说的CoroutineScope(Dispatchers.Main).launch()。 -
为什么要把监听器封装在协程中呢?它已经在后台线程上运行
标签: firebase kotlin firebase-realtime-database firebase-authentication kotlin-coroutines