一、概念
PendingIntent表示一种处于pending状态的Intent,就是说接下来有一个Intent将在某个特定的时刻发生。可以看出PendingIntent和Intent的区别在于,PendingIntent是在将来的某个不确定的时刻发生,而Intent是立刻发生的。PendingIntent的典型使用场景是给RemoteViews添加点击事件。
PendingIntent是Android系统管理并持有的用于描述和获取原始数据的对象的标志(引用)。也就是说,即便创建该PendingIntent对象的进程被杀死了,这个PendingItent对象在其他进程中还是可用的。
二、使用
PendingIntent支持三种待定意图:启动Activity、启动Service和发送广播。
1.方法定义
public static PendingIntent getActivity(Context context, int requestCode,
Intent intent, @Flags int flags)
public static PendingIntent getService(Context context, int requestCode,
@NonNull Intent intent, @Flags int flags)
public static PendingIntent getBroadcast(Context context, int requestCode,
Intent intent, @Flags int flags)
2.匹配规则
如果两个PendingIntent它们内部的Intent相同并且requestCode也相同,那么这两个PendingIntent就是相同的。
如果两个Intent的ComponentName和intent-filter都相同,那么这个两个Intent是相同的,而Extras不参与Intent的匹配过程。
3.flags参数
FLAG_ONE_SHOT:当前描述的PendingIntent只能被使用一次,然后它就会被自动cancel,如果后续还有相同的PendingIntent,那么它们的send方法就会调用失败。对于通知栏消息来说,如果采用此标记位,那么同类的通知只能使用一次,后续的通知单击后将无法打开。
FLAG_NO_CREATE:当前描述的PendingIntent不会主动创建,如果当前PendingIntent之前不存在,那么getActivity、getService和getBroadcast方法会直接返回null,即获取PendingIntent失败。该标记位很少使用。
FLAG_CANCEL_CURRENT:当前描述的PendingIntent如果已经存在,那么它们都会被cancel,然后系统会创建一个新的PendingIntent。对于通知栏来说,那些被cancel的消息单击后将无法打开。
FLAG_UPDATE_CURRENT:当前描述的PendingIntent如果已经存在,那么它们都会被更新,即它们的Intent中的Extras会被替换成最新的。
4.通知栏消息
notificationManager.notify(id, notification):
如果id为常量,那么多次调用notify只能弹出一个通知,后续的通知会把前面的通知完全替代掉,而如果每次id都不同,那么多次调用notify会弹出多个通知。
当每次id都不同时,如果PendingIntent不匹配,那么这些通知不会互相影响。
当每次id都不同时,如果PendingIntent匹配,分情况:
(1)如果采用FLAG_ONE_SHOT标记位,那么后续通知中的PendingIntent会和第一条通知保持完全一致,包括其中的Extras,单击任何一条通知后,剩下的通知均无法再打开,当所有的通知都被清除后,会再次重复这个过程。
(2)如果采用FLAG_CANCEL_CURRENT标记位,那么只有最新的通知可以打开,之前弹出的所有通知均无法打开。
(3)如果采用FLAG_UPDATE_CURRENT标记位,那么之前弹出的通知中的PendingIntent会被更新,最终它们和最新的一条通知保持完全一致,包括其中的Extras,并且这些通知都是可以打开的。