Intent Extra莫名丢失求助:PendingIntent传递Extra异常排查
这个问题其实是Android系统中PendingIntent的复用机制导致的,很多开发者都会踩这个坑!
当你创建PendingIntent时,系统会先检查是否已经存在一个"匹配"的PendingIntent:系统通过Intent.filterEquals()方法来判断两个Intent是否匹配,这个方法只会对比Intent的action、data、type、category、component这几个字段,完全不会考虑Intent中的Extra数据。
回到你的场景:你之前已经通过new Intent(this, B.class)启动过Activity B,当你再次用同样的component(也就是B.class)创建Intent并生成PendingIntent时,系统会认为这是同一个PendingIntent,直接复用之前的实例——而之前的Intent里并没有"bar"这个Extra,所以你拿到的PendingIntent自然就没有你新添加的Extra了。
针对这个问题,有几个可靠的解决方案,你可以根据自己的场景选择:
1. 给Intent设置唯一的Action
给用于生成PendingIntent的Intent设置一个独一无二的Action,这样系统就不会把它和之前的Intent判定为匹配:
Intent intent = new Intent(context, B.class); intent.setAction("com.yourpackage.RESTART_B_" + System.currentTimeMillis()); // 用时间戳保证唯一 intent.putExtra("bar", true); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
2. 使用唯一的requestCode
在调用PendingIntent.getActivity()(或者对应的getService/getBroadcast)时,传入一个唯一的requestCode参数,不同的requestCode会让系统认为是不同的PendingIntent:
int uniqueRequestCode = 1001; // 可以用自增数、时间戳或者其他唯一标识 Intent intent = new Intent(context, B.class); intent.putExtra("bar", true); PendingIntent pendingIntent = PendingIntent.getActivity(context, uniqueRequestCode, intent, PendingIntent.FLAG_IMMUTABLE);
3. 使用合适的PendingIntent Flags
如果确实需要复用PendingIntent的实例,但要更新它的Extra数据,可以使用FLAG_UPDATE_CURRENT这个Flag,它会让系统更新已存在的PendingIntent的Extra内容:
Intent intent = new Intent(context, B.class); intent.putExtra("bar", true); // FLAG_UPDATE_CURRENT会替换已有PendingIntent的Extra PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
注意:如果你的应用适配Android 12及以上,需要加上
FLAG_IMMUTABLE或FLAG_MUTABLE(根据是否需要修改PendingIntent内容),否则会抛出异常。
内容的提问来源于stack exchange,提问作者LLL

