我应该在FirebaseMessagingService的onMessageReceived()中使用协程吗



我正在使用MVVM设计模式开发一个Android应用程序。

我有一个扩展FirebaseMessagingService的类FCMService

如您所知,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)
}
}
}

我读了一篇stackerflow帖子,发现onMessageReceived()函数在后台线程中执行,在onMessageReceived(RemoteMessage消息(中完成的所有工作都应该同步完成。

所以,以下是我的问题,

  1. 我应该在onMessageRecevied()函数中使用CoroutineScope(Dispatchers.IO).lauch {}吗?

  2. 如果没有,那么我可以只使用普通函数,而不是挂起存储库中的函数,并且我可以在没有CoroutineScope(Dispatchers.IO).launch {}的情况下从onMessageReceived()调用它。从建筑设计的角度来看,这是正确的吗?

  3. 这是一个关于Coroutine的问题,但正如你所看到的,我在FCMService中通过CoroutineScope(Dispatchers.IO).lauch{ repository.save(remoteMessage) }在IO线程中启动了一个新的协同程序,但我也在Repository中通过withContext(Dispatchers.IO) { someDAO.save(removeMessage) }将协同程序上下文从IO切换到IO。我觉得withContext(Dispatchers.IO) { someDAO.save(removeMessage) }没有必要,因为我正在从IO切换到IO。我说得对吗?

我会尽力回答。现在来回答您的问题。

Should I use CoroutineScope(Dispatchers.IO).lauch {} in onMessageRecevied() function?

我不认为这有任何问题。Firebase消息服务基本上仍然是一项服务,因此应该不会有任何问题。我建议您创建一个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?

我建议您仍然使用您的Coroutine Scope,而不是直接使用普通函数,因为无论怎样,都建议使用带有Coroutines的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),只是为了与您的其他结构保持一致。

相关内容

  • 没有找到相关文章

最新更新