在Android中,我们常常使用PendingIntent来表达一种“留待日后处理”的意思。从这个角度来说,PendingIntent可以被理解为一种特殊的异步处理机制。不过,单就命名而言,PendingIntent其实具有一定误导性,因为它既不继承于Intent,也不包含Intent,它的核心可以粗略地汇总成四个字——“异步激发”。
很明显,这种异步激发常常是要跨进程执行的。比如说A进程作为发起端,它可以从系统“获取”一个PendingIntent,然后A进程可以将PendingIntent对象通过binder机制“传递”给B进程,再由B进程在未来某个合适时机,“回调”PendingIntent对象的send()动作,完成激发。
PendingIntent 是 Android 提供的一种用于外部程序调起自身程序的能力,生命周期不与主程序相关。外部程序通过 PendingIntent 只能调用起三种组件:
- Activity
- Service
- Broadcast
PendingIntent 的使用场景有三个:
- 使用 AlarmManager 设定闹钟
- 在系统状态栏显示 Notification
- 在桌面显示 Widget
PendingIntent 也只能通过下列的静态方法获取:
1 | // 获取 Broadcast 关联的 PendingIntent |
坦白说,这几个函数的命名可真不怎么样,所以我们简单解释一下。上面的getActivity()
的意思其实是,获取一个PendingIntent对象,而且该对象日后激发时所做的事情是启动一个新activity。也就是说,当它异步激发时,会执行类似Context.startActivity()
那样的动作。相应地,getBroadcast()
和getService()
所获取的PendingIntent对象在激发时,会分别执行类似Context.sendBroadcast()
和Context.startService()
这样的动作。
参数flags在文档中是这样解析的:
**flags:**目前为止只提供FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT这四个flag
**FLAG_ONE_SHOT:**利用 FLAG_ONE_SHOT获取的PendingIntent只能使用一次,即使再次利用上面三个方法重新获取,再使用PendingIntent也将失败。
**FLAG_NO_CREATE:**利用FLAG_NO_CREAT获取的PendingIntent,若描述的Intent不存在则返回NULL值.
**FLAG_CANCEL_CURRENT:**如果描述的PendingIntent已经存在,则在产生新的Intent之前会先取消掉当前的。你可用使用它去检索新的Intent,如果你只是想改变Intent中的额外数据的话。通过取消先前的Intent,可用确保只有最新的实体可用启动它。如果这一保证不是问题,考虑flag_update_current。
**FLAG_UPDATE_CURRENT:**最经常使用的是FLAG_UPDATE_CURRENT,因为描述的Intent有 更新的时候需要用到这个flag去更新你的描述,否则组件在下次事件发生或时间到达的时候extras永远是第一次Intent的extras。
上面4个flag中最经常使用的是FLAG_UPDATE_CURRENT,因为描述的Intent有 更新的时候需要用到这个flag去更新你的描述,否则组件在下次事件发生或时间到达的时候extras永远是第一次Intent的extras。
使用 FLAG_CANCEL_CURRENT也能做到更新extras,只不过是先把前面的extras清除,另外FLAG_CANCEL_CURRENT和 FLAG_UPDATE_CURRENT的区别在于能否新new一个Intent,FLAG_UPDATE_CURRENT能够新new一个 Intent,而FLAG_CANCEL_CURRENT则不能,只能使用第一次的Intent。
此外还需要注意参数:
int requestCode: Private request code for the sender (currently not used).
PendingIntent contentIntent = PendingIntent.getActivity(context, num, intent, PendingIntent.FLAG_UPDATE_CURRENT);
对于FLAG_UPDATE_CURRENT,如果上面的requestCode 为常量,则对于先后出现的若干Notification,则所有对应的Intent里面的extra被更新为最新的,就是全部同一为最后一次的。
相反,如果num每次不一样,则里面的Inent的数据没被更新。
对于FLAG_CANCEL_CURRENT,则只响应最前面的第一条Notifiacation,后面所有的不响应….
使用请参考:Android中的PendingIntent传送widgetID总是最后一个
flags:
(1) android.app.PendingIntent.FLAG_UPDATE_CURRENT
如果PendingIntent已经存在,保留它并且只替换它的extra数据。
(2) android.app.PendingIntent.FLAG_CANCEL_CURRENT
如果PendingIntent已经存在,那么当前的PendingIntent会取消掉,然后产生一个新的PendingIntent。
(3) android.app.PendingIntent.FLAG_ONE_SHOT
PendingIntent只能使用一次。调用了实例方法send()之后,它会被自动cancel掉,再次调用send()方法将失败。
(4) android.app.PendingIntent.FLAG_NO_CREATE
如果PendingIntent不存在,简单了当返回null。
requestCode:
如果一次推送几个通知到通知栏,且requestCode一致的话,PendingIntent里里边的数据会被最后一个推送过来的替换掉,即:第一个推送的数据会跟第二个一样。这点一定要注意。