PendingIntent

参考:

彻底认识 PendingIntent

Intent和PendingIntent的区别

Intent 和 PendingIntent 的区别

intent英文意思是意图,pending表示即将发生或来临的事情。
PendingIntent这个类用于处理即将发生的事情。比如在通知Notification中用于跳转页面,但不是马上跳转。

Intent 是及时启动,intent 随所在的activity 消失而消失。
PendingIntent 可以看作是对intent的包装,通常通过getActivity,getBroadcast ,getService来得到pendingintent的实例,
当前activity并不能马上启动它所包含的intent,而是在外部执行 pendingintent时,调用intent的。
正由于pendingintent中 保存有当前App的Context,使它赋予外部App一种能力,
使得外部App可以如同当前App一样的执行pendingintent里的 Intent, 就算在执行时当前App已经不存在了,
也能通过存在pendingintent里的Context照样执行Intent。另外还可以处理intent执行后的操作。
常和alermanger 和notificationmanager一起使用。
Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,而Pendingintent,一般用在 Notification上,
可以理解为延迟执行的intent,PendingIntent是对Intent一个包装。

Intent

Intent 是意图的意思。Android 中的 Intent 正是取自这个意思,它是一个消息对象,通过它,Android 系统的四大组件能够方便的通信,并且保证解耦。

Intent 可以说明某种意图,携带一种行为和相应的数据,发送到目标组件。

IntentFilter 与 Intent 配套使用,它声明了一个组件接受某个 Intent。

PendingIntent

PendingIntent 是对 Intent 的封装,关键的不同在于:

A组件 创建了一个 PendingIntent 的对象然后传给 B组件,B 在执行这个 PendingIntent 的 send 时候,它里面的 Intent 会被发送出去,而接受到这个 Intent 的 C 组件会认为是 A 发的。

B 以 A 的权限和身份发送了这个 Intent。

比如,我们的 Activity 如果设置了 exported = false,其他应用如果使用 Intent 就访问不到这个 Activity,但是使用 PendingIntent 是可以的。

综上所述,PendingIntent 有两个特点:

将某个动作的触发时机交给其他应用

让那个应用代表自己去执行那个动作(权限都给他了)

获取PendingIntent常用的三个静态方法

public static PendingIntent getActivity(Context context, int requestCode,
		Intent intent, @Flags int flags) {
}

public static PendingIntent getBroadcast(Context context, int requestCode,
		Intent intent, @Flags int flags) {
}

public static PendingIntent getService(Context context, int requestCode,
		@NonNull Intent intent, @Flags int flags) {
}	

它们的参数都相同,都是四个:Context, requestCode, Intent, flags。
Context 不必多说,要想让其他组件代替自己办事,当然要将自己的上下文传给它。
action, requestCode 和 Intent 共同来标志一个行为的唯一性,什么意思呢?

简单的说,我们通过相同的方法(action), 相同的 requestCode 和相同的 Intent 获取到的 PendingIntent,
虽然可能不是同一个对象,但是,却是代表同一个东西,之所以这样看 flags 参数就知道了。

flag

//该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,
//PendingIntent将自动调用cancel()进行销毁,
//那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
//即:只执行一次, 在调用了 send 以后自动调用 cancel,不能在调用 send 了。
public static final int FLAG_ONE_SHOT = 1<<30;

//如果当前系统中不存在相同的PendingIntent对象,
//系统将不会创建该PendingIntent对象而是直接返回null。
//即:不创建新的,如果我们之前设置过,这次就能获取到,否则,返回 null。
public static final int FLAG_NO_CREATE = 1<<29;

//如果当前系统中已经存在一个相同的PendingIntent对象,
//那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。
//即:如果之前设置过,就取消掉, 重新创建个新的
public static final int FLAG_CANCEL_CURRENT = 1<<28;

//如果系统中有一个和你描述的PendingIntent对等的PendingInent,
//那么系统将使用该PendingIntent对象,
//但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,
//例如更新Intent中的Extras。
//即:如果之前设置过,就更新它。更新什么呢,Intent 的 Extras
public static final int FLAG_UPDATE_CURRENT = 1<<27;

// 设置 Intent 在 send 的时候不能更改
public static final int FLAG_IMMUTABLE = 1<<26;

注意:传入0(第四个参数),就意味着你不打算使用任何一种flag来控制PendingIntent的创建。

发送 PendingIntent

send 是触发 PendingIntent 包含的行为,它有很多重载形式,我们通常的开发用不到他,
除非我们做桌面程序开发或者 Android Framework 开发。
这里我们只是大体说明一下,可以传给它一个 Intent 来对它原来的 Intent 做修改,
但是如果目标设置了 FLAG_IMMUTABLE 则给参数忽略。可以设置 callback 当发送完成获得回调,
并且可以通过设置handler决定回调发生的线程。

取消 PendingIntent

只有设置 PendingIntent 的原来的应用可以取消它,发送方只能发送,当一个 PendingIntent 被取消后,发送则不会成功。

PendingIntent 的使用场景

已知的使用场景是:

通知,在点击通知时执行调起本应用的操作,当然也可以执行其他操作
闹钟,定时执行某个操作
桌面小部件,点击小部件时执行某个操作
通知,闹钟,桌面小部件,都是运行在其他应用中的,但是给我们的感知就像是我们自己的应用的一部分。

内部实现

大体的原理是: A应用希望让B应用帮忙触发一个行为,这是跨应用的通信,需要 Android 系统作为中间人,
这里的中间人就是 ActivityManager。 A应用创建建 PendingIntent,在创建 PendingIntent 的过程中,
向 ActivityManager 注册了这个 PendingIntent,所以,即使A应用死了,当它再次苏醒时,只要提供相同的参数,
还是可以获取到之前那个 PendingIntent 的。当 A 将 PendingIntent 调用系统 API 比如 AlarmManager.set(),
实际是将权限给了B应用,这时候, B应用可以根据参数信息,来从 ActivityManager 获取到 A 设置的 PendingIntent。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值