You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

onNewIntent()调用异常及Intent extras丢失问题求助(singleTop模式)

解决通知点击跳转指定Fragment的双场景异常问题

问题背景

需求是创建通知,点击时打开应用并根据Intent extras中的数据跳转到指定Fragment,已将目标Activity的启动模式设置为singleTop,但遇到两个异常:

  • 应用处于杀死状态:onCreate()执行正常,跳转逻辑能运行,但后续onNewIntent()会被多次调用
  • 应用处于前台状态:onNewIntent()会被触发,但Intent中没有传递的extras数据

原创建通知代码

notificationIntent.flags = (Intent.FLAG_ACTIVITY_CLEAR_TOP
        or Intent.FLAG_ACTIVITY_SINGLE_TOP)
notificationIntent.putExtra(Constants.MEDICATION_EXTRA, titleText)
contentIntent = PendingIntent.getActivity(
    context, 0,
    notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

val id = notificationHelper.postNotification(
    notificationHelper.createNotification(
        contentText = contentText,
        contentIntent = contentIntent,
        autoCancel = true,
        title = titleText,
    )
)

问题原因分析

  1. 前台状态extras丢失:PendingIntent的requestCode固定为0,会导致新通知复用旧的PendingIntent实例,extras无法更新;另外singleTop模式下未主动替换Activity的Intent,导致后续获取的仍是旧Intent。
  2. 杀死状态onNewIntent多次调用:FLAG_ACTIVITY_CLEAR_TOP会清理栈内上方的Activity并重启目标Activity,结合singleTop可能触发多次生命周期回调,导致onNewIntent重复调用。

解决方案

1. 修改通知创建代码,确保PendingIntent唯一且Intent flags合理

// 生成唯一requestCode,避免复用旧PendingIntent
val requestCode = System.currentTimeMillis().toInt()
// 替换FLAG_ACTIVITY_CLEAR_TOP为FLAG_ACTIVITY_REORDER_TO_FRONT,避免栈清理引发的重复回调
notificationIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
notificationIntent.putExtra(Constants.MEDICATION_EXTRA, titleText)
contentIntent = PendingIntent.getActivity(
    context,
    requestCode,
    notificationIntent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

val id = notificationHelper.postNotification(
    notificationHelper.createNotification(
        contentText = contentText,
        contentIntent = contentIntent,
        autoCancel = true,
        title = titleText,
    )
)

2. 在目标Activity中正确处理Intent

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 处理应用杀死状态下的通知Intent
        handleNotificationJump(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let {
            // 替换Activity持有的Intent为最新的通知Intent
            setIntent(it)
            // 处理应用前台状态下的通知Intent
            handleNotificationJump(it)
        }
    }

    private fun handleNotificationJump(intent: Intent) {
        val extraData = intent.getStringExtra(Constants.MEDICATION_EXTRA)
        extraData?.takeIf { it.isNotEmpty() }?.let {
            // 执行跳转到指定Fragment的逻辑,示例用FragmentManager实现
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragment_container, TargetFragment.newInstance(it))
                .addToBackStack(null)
                .commit()
        }
    }
}

关键修改说明

  • 唯一requestCode:避免不同通知的PendingIntent复用,确保每次通知的extras能正确传递到Intent中
  • FLAG_ACTIVITY_REORDER_TO_FRONT:仅将目标Activity带到前台,不清理栈内其他Activity,减少不必要的生命周期回调,避免onNewIntent多次触发
  • onNewIntent中调用setIntent:替换Activity原有的Intent为最新的通知Intent,确保后续获取的Intent包含正确的extras
  • 统一跳转逻辑:将跳转逻辑抽离到单独方法,避免onCreate和onNewIntent中重复编写代码,保证逻辑一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 02:43:18