应用关闭时接收FCM触发ANR问题求助
解决FCM消息触发应用关闭状态下的ANR问题
问题背景
应用处于关闭状态时接收FCM消息,触发大量ANR,ANR日志指向FirebaseInstanceIdReceiver处理com.google.android.c2dm.intent.RECEIVE意图。已尝试升降级Firebase SDK、配置指定Manifest组件,但问题仍未解决。
排查与解决步骤
1. 替换废弃的FirebaseInstanceIdReceiver
从Firebase SDK 21.0.0版本开始,FirebaseInstanceIdReceiver已被废弃,官方推荐使用FirebaseMessagingReceiver替代。修改Manifest中的接收器配置:
<receiver android:name="com.google.firebase.messaging.FirebaseMessagingReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="${applicationId}" /> </intent-filter> </receiver>
旧接收器在新版本SDK中存在后台场景下的兼容性问题,是触发ANR的常见诱因。
2. 优化FirebaseMessagingService的消息处理逻辑
广播接收器的主线程执行超时限制为10秒,一旦onMessageReceived中存在耗时操作就会触发ANR:
- 避免在主线程执行网络请求、数据库读写等阻塞任务,改用协程、AsyncTask或WorkManager移至后台处理
- 显示通知的操作直接调用
NotificationManagerCompat完成,不要附加复杂逻辑 - 数据消息的解析、业务处理全部放在后台线程执行
示例优化后的代码:
override fun onMessageReceived(remoteMessage: RemoteMessage) { // 通知消息直接快速处理 remoteMessage.notification?.let { val notification = NotificationCompat.Builder(this, getString(R.string.notification_channel_id)) .setContentTitle(it.title) .setContentText(it.body) .setSmallIcon(R.drawable.ic_notification) .build() NotificationManagerCompat.from(this).notify(System.currentTimeMillis().toInt(), notification) } // 数据消息移至后台处理 CoroutineScope(Dispatchers.IO).launch { processDataPayload(remoteMessage.data) } }
3. 排查应用启动阶段的阻塞操作
应用关闭时接收FCM消息会触发进程重启,若Application或启动页的onCreate中存在耗时初始化(如SDK预加载、大量IO操作),会直接导致ANR:
- 将非必要的初始化逻辑延迟到首屏启动后执行
- 对必须提前初始化的SDK,采用异步初始化方式
4. 检查FCM消息类型与payload大小
- 若发送的是通知消息(含
notification字段),系统会直接处理显示,不会触发onMessageReceived;若仍出现ANR,可尝试改为纯数据消息(仅含data字段),由应用自行控制处理流程 - 确保消息payload不超过FCM限制的4KB,过大的数据会增加解析耗时
5. 用StrictMode定位主线程阻塞
在Debug版本中启用StrictMode,检测主线程的违规操作:
override fun onCreate() { if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .build()) StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .build()) } super.onCreate() }
通过Logcat中的StrictMode警告,精准定位主线程中耗时的代码块。
内容的提问来源于stack exchange,提问作者XaMi
相关产品推荐
相关产品推荐

