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
相关产品推荐
相关产品推荐

