App被杀死状态下点击Firebase通知跳转指定Activity问题求助
问题根因
- 应用被杀死属于冷启动场景,你原先配置的
Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOPFlag组合不会自动构建Activity返回栈,直接启动目标Activity时返回栈为空,点击返回键会直接退出应用;同时冷启动Activity只会触发onCreate生命周期,不会走onNewIntent回调,所以你写在onNewIntent里的消息获取逻辑完全不会执行,自然拿不到通知内容。 - Firebase推送分数据消息和通知消息两类:如果推送payload带
notification字段,应用被杀死时Firebase会自动弹系统默认通知,点击后默认启动Manifest中注册的LAUNCHER类(也就是你的MainActivity),不会执行你在onMessageReceived里写的自定义通知构建逻辑,这就是冷启动点通知只打开MainActivity的核心原因。
分步解决方案
1. 调整推送下发规则
所有推送使用纯data payload格式,不要携带notification字段,保证应用在前台、后台、被杀死三种状态下,onMessageReceived回调都会正常触发,你的自定义通知逻辑才能全场景生效。
2. 修复通知点击的返回栈逻辑
使用TaskStackBuilder构建带正确层级的PendingIntent,替换之前直接给目标Activity创建PendingIntent的写法,保证从通知打开详情页后,按返回键能正常回到MainActivity,不会直接退出应用。
替换sendNotification方法的原有实现:
private void sendNotification(String msg) { mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE); Intent notifyIntent = new Intent(ctx, NotificationDetailsActivity.class); notifyIntent.putExtra("NotificationMessage", msg); // 构建带层级的返回栈 TaskStackBuilder stackBuilder = TaskStackBuilder.create(ctx); // 先添加栈内的MainActivity,作为返回时的上一级页面 stackBuilder.addNextIntentWithParentStack(new Intent(ctx, MainActivity.class)); // 将通知详情页放在栈顶 stackBuilder.addNextIntent(notifyIntent); // 生成带返回栈的PendingIntent PendingIntent notifyPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( ctx, NOTIFICATION_CHANNEL_ID) .setContentText(msg) .setPriority(NotificationCompat.PRIORITY_HIGH) .setSmallIcon(android.R.drawable.ic_popup_reminder) .setAutoCancel(true) .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL) .setContentIntent(notifyPendingIntent) .setSound(defaultSoundUri); mNotificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); if (NotificationDetailsActivity.isVisible) { NotificationDetailsActivity.notificationDetailsActivity.ToastNotify(msg); } }
同时在AndroidManifest.xml中给NotificationDetailsActivity配置父Activity属性,和TaskStackBuilder逻辑匹配:
<activity android:name=".NotificationDetailsActivity" android:exported="false"> <!-- 使用support库时用这个配置 --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" /> <!-- 使用AndroidX依赖时替换为下面的配置 <meta-data android:name="androidx.core.app.PARENT_ACTIVITY" android:value=".MainActivity" /> --> </activity>
3. 补全详情页的参数获取逻辑
把通知消息的解析逻辑抽成公共方法,同时在onCreate和onNewIntent中调用,覆盖冷启动和栈顶复用两种场景:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_notification_details); // 冷启动场景从getIntent取参数 handleNotifyMessage(getIntent()); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // 栈顶复用场景从新传入的intent取参数 handleNotifyMessage(intent); } private void handleNotifyMessage(Intent intent) { Bundle extras = intent.getExtras(); if(extras != null && extras.containsKey("NotificationMessage")){ String msg = extras.getString("NotificationMessage"); TextView helloText = findViewById(R.id.text_hello); helloText.setText(msg); } }
4. 清理冗余代码
删除之前在MainActivity中添加的onNewIntent通知参数获取逻辑,MainActivity不需要做通知中转,按上述配置后通知会直接打开详情页,返回时自然回到MainActivity。
测试注意事项
- 不要用Android Studio的「Stop」按钮模拟应用杀死场景,这个操作会给应用打上强制停止标记,系统会拦截通知启动逻辑,测试结果不准。正确模拟方式是把应用切到后台,从最近任务列表手动划掉应用。
- 测试前确认推送payload是纯data格式,没有
notification字段,否则杀死状态下会走Firebase默认通知逻辑,不会触发你写的自定义通知代码。
内容的提问来源于stack exchange,提问作者Kalyani Bandari
相关产品推荐
相关产品推荐

