我应该在 FirebaseMessagingService 的 onMessageReceived() 中使用协程吗?
Should I use coroutine in onMessageReceived() of FirebaseMessagingService?
我正在使用 MVVM 设计模式开发 Android 应用程序。
我有一个 class FCMService
扩展 FirebaseMessagingService
.
如您所知,FCMService
覆盖 onMessageReceived(remoteMessage: RemoteMessage)
函数。
因此,每当我在 onMessageReceived()
函数中收到一条消息时,我想通过存储库将其保存到房间数据库中。
看起来像下面的代码。
class FCMService : FirebaseMessagingService(), KodeinAware {
override val kodein by closestKodein()
private val repository: Repository by instance()
private val scope: CoroutineScope by instance()
override fun onNewToken(token: String) {
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
CoroutineScope(Dispatchers.IO).lauch{ repository.save(remoteMessage) }
}
}
class Repository {
suspend fun save(remoteMessage: RemoteMessage) {
withContext(Dispatchers.IO) {
someDAO.save(removeMessage)
}
}
}
我阅读了 Whosebug 并发现 onMessageReceived()
函数在后台线程中执行,并且在 onMessageReceived(RemoteMessage message) 中完成的所有工作都应该同步完成。
所以,这是我的问题
我应该在 onMessageRecevied()
函数中使用 CoroutineScope(Dispatchers.IO).lauch {}
吗?
如果没有,那么我可以只使用正常功能,而不是在存储库中暂停功能,我可以从 onMessageReceived()
调用它而不用 CoroutineScope(Dispatchers.IO).launch {}
。请问从架构设计的角度来说是否正确?
这是一个关于 Coroutine 的问题,但是,正如你所看到的,我在 FCMService
中通过 CoroutineScope(Dispatchers.IO).lauch{ repository.save(remoteMessage) }
在 IO 线程中启动了一个新的协程,但我也从 IO 切换了 coroutineContext通过 withContext(Dispatchers.IO) { someDAO.save(removeMessage) }
在 Repository
到 IO。我觉得withContext(Dispatchers.IO) { someDAO.save(removeMessage) }
是不必要的,因为我是从IO切换到IO。请问我说的对吗?
我会尽我所知尽力回答。现在来回答你的问题。
Should I use CoroutineScope(Dispatchers.IO).lauch {} in onMessageRecevied() function?
我不认为它有任何问题。 Firebase Messaging Service 基本上仍然是一个服务,所以应该没有问题。我建议您创建一个 Coroutine 范围,如果出现任何问题,您可以取消该范围。通常在 ViewModel 中我们使用 viewModelScope
所以你可以这样做
val job = SupervisorJob()
CoroutineScope(job).launch {
// Your Stuff here
}
override fun onDestroy() {
job.cancel()
super.onDestroy()
}
第二个问题
If no, then I can just use normal function, not suspend function in repository and I can call it from onMessageReceived() without CoroutineScope(Dispatchers.IO).launch {}. Is it correct in terms of architectural design point of view please?
我建议您仍然使用协程作用域,而不是直接使用普通函数,因为无论如何都建议使用带有协程的 Room,即使从架构的角度来看也不会造成伤害。
第三
It's a question about Coroutine but, as you can see that I launched a new coroutine in IO thread by CoroutineScope(Dispatchers.IO).lauch{ repository.save(remoteMessage) } in FCMService but I also switch the coroutineContext from IO to IO by withContext(Dispatchers.IO) { someDAO.save(removeMessage) } in Repository. I feel that withContext(Dispatchers.IO) { someDAO.save(removeMessage) } is unnecessary because I am switching from IO to IO. Am I right please?
既然您已经在使用 Dispatchers.IO
,您就不再需要它了,这是正确的。让它保持 withContext(Dispatcher.IO)
只是为了与您的其他结构保持一致。
我正在使用 MVVM 设计模式开发 Android 应用程序。
我有一个 class FCMService
扩展 FirebaseMessagingService
.
如您所知,FCMService
覆盖 onMessageReceived(remoteMessage: RemoteMessage)
函数。
因此,每当我在 onMessageReceived()
函数中收到一条消息时,我想通过存储库将其保存到房间数据库中。
看起来像下面的代码。
class FCMService : FirebaseMessagingService(), KodeinAware {
override val kodein by closestKodein()
private val repository: Repository by instance()
private val scope: CoroutineScope by instance()
override fun onNewToken(token: String) {
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
CoroutineScope(Dispatchers.IO).lauch{ repository.save(remoteMessage) }
}
}
class Repository {
suspend fun save(remoteMessage: RemoteMessage) {
withContext(Dispatchers.IO) {
someDAO.save(removeMessage)
}
}
}
我阅读了 Whosebug onMessageReceived()
函数在后台线程中执行,并且在 onMessageReceived(RemoteMessage message) 中完成的所有工作都应该同步完成。
所以,这是我的问题
我应该在
onMessageRecevied()
函数中使用CoroutineScope(Dispatchers.IO).lauch {}
吗?如果没有,那么我可以只使用正常功能,而不是在存储库中暂停功能,我可以从
onMessageReceived()
调用它而不用CoroutineScope(Dispatchers.IO).launch {}
。请问从架构设计的角度来说是否正确?这是一个关于 Coroutine 的问题,但是,正如你所看到的,我在
FCMService
中通过CoroutineScope(Dispatchers.IO).lauch{ repository.save(remoteMessage) }
在 IO 线程中启动了一个新的协程,但我也从 IO 切换了 coroutineContext通过withContext(Dispatchers.IO) { someDAO.save(removeMessage) }
在Repository
到 IO。我觉得withContext(Dispatchers.IO) { someDAO.save(removeMessage) }
是不必要的,因为我是从IO切换到IO。请问我说的对吗?
我会尽我所知尽力回答。现在来回答你的问题。
Should I use CoroutineScope(Dispatchers.IO).lauch {} in onMessageRecevied() function?
我不认为它有任何问题。 Firebase Messaging Service 基本上仍然是一个服务,所以应该没有问题。我建议您创建一个 Coroutine 范围,如果出现任何问题,您可以取消该范围。通常在 ViewModel 中我们使用 viewModelScope
所以你可以这样做
val job = SupervisorJob()
CoroutineScope(job).launch {
// Your Stuff here
}
override fun onDestroy() {
job.cancel()
super.onDestroy()
}
第二个问题
If no, then I can just use normal function, not suspend function in repository and I can call it from onMessageReceived() without CoroutineScope(Dispatchers.IO).launch {}. Is it correct in terms of architectural design point of view please?
我建议您仍然使用协程作用域,而不是直接使用普通函数,因为无论如何都建议使用带有协程的 Room,即使从架构的角度来看也不会造成伤害。
第三
It's a question about Coroutine but, as you can see that I launched a new coroutine in IO thread by CoroutineScope(Dispatchers.IO).lauch{ repository.save(remoteMessage) } in FCMService but I also switch the coroutineContext from IO to IO by withContext(Dispatchers.IO) { someDAO.save(removeMessage) } in Repository. I feel that withContext(Dispatchers.IO) { someDAO.save(removeMessage) } is unnecessary because I am switching from IO to IO. Am I right please?
既然您已经在使用 Dispatchers.IO
,您就不再需要它了,这是正确的。让它保持 withContext(Dispatcher.IO)
只是为了与您的其他结构保持一致。