You need to enable JavaScript to run this app. FirebaseMessagingService创建后立即销毁,如何实现服务长期保活?
优惠活动
大模型
产品
解决方案
定价
更多

FirebaseMessagingService创建后立即销毁,如何实现服务长期保活?

问题解决方案

问题根源

  • 你当前使用的是普通后台服务,Android 8.0及以上系统对后台服务有严格的运行限制,没有前台展示通知的后台服务会在数分钟内被系统主动回收,这就是你启动服务后立刻被销毁的原因。服务销毁触发onDestroy中的广播发送逻辑,再次触发重启,就陷入了无限循环。
  • 你在MainActivity.onDestroy中发送重启广播的逻辑完全多余,Activity销毁不代表应用进程销毁,该逻辑会额外触发不必要的重启请求,加剧循环问题。
  • 广播接收器中手动修改isRunning状态的时机错误,服务还没启动成功就提前标记为运行,会导致状态判断混乱。

修复步骤

1. 修改服务为前台服务,避免被系统回收

在MessagingService的onCreate方法中新增前台服务启动逻辑,服务运行时会在通知栏展示常驻通知,获得更高的系统优先级,不会被随便回收:

override fun onCreate() {
    super.onCreate()
    Log.d("MessagingService", "I am created")
    isRunning = true
    //  Android 8.0 以上启动前台服务
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channelId = "service_keep_alive_channel"
        val channel = NotificationChannel(
            channelId,
            "后台运行通知",
            NotificationManager.IMPORTANCE_LOW // 低重要性,不会弹出提示音
        )
        val notificationManager = getSystemService(NotificationManager::class.java)
        notificationManager.createNotificationChannel(channel)

        val notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle("推送服务运行中")
            .setContentText("用于及时接收消息通知")
            .setSmallIcon(R.drawable.mlearn_logo)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()
        // 启动前台服务,注意通知ID不要和现有推送ID重复
        startForeground(1, notification)
    }
    FirebaseAuth.getInstance().addAuthStateListener(this)
}

2. 修改广播接收器的服务启动逻辑

Android 8.0及以上后台启动服务必须使用startForegroundService,同时删掉提前修改isRunning的代码,等待服务启动后在onCreate中自行修改状态,避免状态错误:

class MessagingServiceRestarter : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Log.d("MessagingService", "Restarter" + MessagingService.isRunning.toString())
        if (!MessagingService.isRunning) {
            val serviceIntent = Intent(context, MessagingService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(serviceIntent)
            } else {
                context.startService(serviceIntent)
            }
        }
    }
}

3. 移除多余的重启触发逻辑

删掉MainActivity中onDestroy方法里的广播发送逻辑,Activity销毁不需要重启服务:

// 完全删除该段代码
override fun onDestroy() {
    val intent = Intent()
    Log.d("MessagingService", "MainActivity" + MessagingService.isRunning.toString())
    intent.action = "restartMessagingService"
    intent.setClass(this, MessagingServiceRestarter::class.java)
    sendBroadcast(intent)
    super.onDestroy()
}

4. 国内厂商适配补充

国内小米、华为、OPPO、VIVO等厂商都有自研的后台进程管理机制,就算开启了前台服务,用户滑掉最近任务后依然可能杀死应用进程。需要引导用户手动给APP开启自启动权限、后台运行权限、锁屏不清理权限,才能保证服务稳定运行。

额外说明

FirebaseMessagingService本身的设计不需要开发者手动保活,高优先级的FCM推送会自动唤醒应用进程接收消息,不需要服务长期在后台运行。手动保活逻辑会增加设备耗电,也可能被系统标记为恶意应用,若你的场景只是正常接收FCM推送,建议直接删掉所有自定义保活逻辑即可。


内容的提问来源于stack exchange,提问作者Richard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 00:18:03