1 PendingIntent概述
PendingIntent
表示一种处于pending状态(待定、等待、即将发生)的意图,也就是将会有一个 Intent(意图)
将在某个时刻发生。PendingIntent和Intent的区别在于,PendingIntent是将在未来某个不确定时刻发生,而Intent是立刻发生。
2 PendingIntent的三种意图
PendingIntent支持三种待定意图:启动Activity、启动Service和发送广播。
-
getActivity(Context context, int requestCode, Intent intent, int flags):该待定意图发生时,效果相当于
Context.startActivity(intent)
| -
getService(Context context, int requestCode, Intent intent, int flags):该待定意图发生时,效果相当于
Context.startService(intent)
-
getBroadcast(Context context, int requestCode, Intent intent, int flags):该待定意图发生时,效果相当于
Context.sendBroadcast(intent)
requestCode
表示PendingIntent发送方的请求码,多数情况下为0即可,另外requestCode会影响到flags的效果。
3 PendingIntent的匹配规则
如果两个PendingIntent它们内部的Intent相同(Intent相同,指的是两个Intent的 ComponentName
和 intent-filter
相同,不包含 Extras
)并且requestCode相同,那么这两个PendingIntent相同。
4 PendingIntent的flags参数
-
FLAG_ONE_SHOT:当前描述的PendingIntent只能被使用一次,然后它就会被自动cancel,如果后续还有相同的PendingIntent,那么它们的
send()
就会调用失败。对于通知栏消息来说,如果采用此标记位,那么同类的通知只能使用一次,后续的通知单击后将无法打开 -
FLAG_NO_CREATE:当前描述的PendingIntent不会主动创建,如果当前PendingIntent之前不存在,那么
getActivity()
、getService()
和getBroadcast()
会直接返回null即获取PendingIntent失败。这个标记位很少见无法单独使用,日常开发不会用到 -
FLAG_CANCEL_CURRENT:当前描述的PendingIntent如果已经存在,那么它们都会被更新,即它们的Intent中的
Extras
会被替换成最新的
5 PendingIntent标志位场景分析
以通知栏消息的场景来分析不同的 flags
标志位产生的不同的效果,以 NotificationManager.notify(1, notification
为例,第一个参数为id。
-
如果id是一个常量,那么不管PendingIntent是否匹配,多次调用
notify()
只能弹出一个通知,后续的通知会把前面的通知替换掉 -
如果id每次都不同:
-
如果PendingIntent不匹配时(这里的匹配是指Intent相同且requestCode相同),不管采用哪种标志位,这些通知都互不干扰
-
如果PendingIntent匹配时:
-
采用了
FLAG_ONE_SHOT
标志位,后续通知中的PendingIntent会和第一条通知保持完全一致,包括其中的Extras
,单击任何一条通知后,剩下的通知均无法再打开,当所有的通知都被清除后,会再次重复这个过程 -
采用
FLAG_CANCEL_CURRENT
标志位,只有最新的通知可以打开,之前弹出的所有通知均无法打开 -
采用
FLAG_UPDATE_CURRENT
标志位,之前弹出的通知中的PendingIntent会被更新,最终它们和最新的一条通知保持完全一致,包括其中的Extras
,并且这些通知都是可以打开的
-
-