Android 从Service发通知点击后Activity被重建,onNewIntent未触发如何解决?
问题原因
你设置的Intent启动Flags被TaskStackBuilder覆盖了。TaskStackBuilder在执行addNextIntentWithParentStack()时,会自动为目标Intent添加符合回退栈逻辑的默认Flags,你预先设置的FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_CLEAR_TOP、FLAG_ACTIVITY_SINGLE_TOP都会被重置失效,导致每次点击通知都会重建Activity实例。
而你在Activity内部创建通知时没有使用TaskStackBuilder,直接构造的PendingIntent会保留你设置的Flags,所以功能正常。
解决方案
分两种场景处理:
场景1:不需要保留回退栈逻辑(点击HomeActivity返回直接回到桌面)
直接弃用TaskStackBuilder,用PendingIntent.getActivity()直接创建PendingIntent即可,代码如下:
val finalIntent = Intent(this, HomeActivity::class.java) finalIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) val pendingIntentFlags : Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE } else { PendingIntent.FLAG_UPDATE_CURRENT } // 直接创建PendingIntent val pendingIntent = PendingIntent.getActivity(context, 0, finalIntent, pendingIntentFlags)
场景2:需要保留回退栈逻辑(点击HomeActivity返回要跳转到指定父Activity)
在addNextIntentWithParentStack之后,手动修改栈中目标Intent的Flags:
val finalIntent = Intent(this, HomeActivity::class.java) val pendingIntentFlags : Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE } else { PendingIntent.FLAG_UPDATE_CURRENT } val pendingIntent : PendingIntent? = TaskStackBuilder.create(context).run { addNextIntentWithParentStack(finalIntent) // 手动修改最后一个(也就是目标HomeActivity)的Intent Flags editIntentAt(intentCount - 1)?.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) getPendingIntent(0, pendingIntentFlags) }
额外注意项
- 建议在
AndroidManifest.xml中为HomeActivity显式指定launchMode:
可以避免部分系统版本下Flags不生效的兼容问题。<activity android:name=".HomeActivity" android:launchMode="singleTop" /> - 如果你的通知会携带不同的Extra参数,需要给
getPendingIntent的第一个参数(请求码)传入不同的值,否则后续通知的Extra会覆盖之前的内容。
内容的提问来源于stack exchange,提问作者user1354879
相关产品推荐
相关产品推荐

