FirebaseMessagingService在 Job尚未完成时就取消了CoroutineScope

移动开发 2026-07-11

在下面的代码片段中,我试图在 onMessageReceived() 中执行挂起函数 MessageHandler.handleMessage(),然而该函数没有完成,因为 ioScope 被取消,原因是在调用了 onDestroy()

class FcmService : FirebaseMessagingService() {
    companion object {
        private const val FCM_KEY_MESSAGE = "message"
    }

    private val conversationsRepo: ConversationsRepoImpl by inject()
    private val chatMessagesRepo: ChatMessagesRepoImpl by inject()
    private val ioScope = CoroutineScope(Dispatchers.IO)

    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)

        val message = message.data[FCM_KEY_MESSAGE] ?: return

        ioScope.launch {
            try {
                MessageHandler.handleMessage(
                    conversationsRepo,
                    chatMessagesRepo,
                    message
                )
            } catch (e: Exception) {
                Log.e("xxx", "Error: ${e.message.toString()}")
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()

        Log.d("xxx", "onDestroy()")
        ioScope.cancel()
    }
}

以下是日志:

onDestroy()
Error: Job was cancelled

如何让挂起函数完成?

解决方案

一旦消息被处理完毕(onMessageReceived结束),服务就会停止。由于你在其中启动了一个新的CoroutineScope,onMessageReceived基本上会立即返回。你的作用域还没开始,一旦开始,onDestroy已经被调用,所以该作用域被取消。

我建议把需要在该作用域中完成的工作延后交给一个新的WorkManager Worker去执行,以完成你正在尝试做的事情。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章