PendingIntent使用解析

PendingIntent 中的单词 “pending” 指延迟或挂起,就是指它是延迟的或挂起的。一句话概括,PendingIntent 一种是支持授权其他应用以当前应用的身份执行包装的 Intent 操作的系统特性。

什么场景下会使用 PendingIntent?

场景 1 - 系统通知消息的点击操作
场景 2 - 桌面Widget的点击操作
场景 3 - 系统闹钟操作
场景 4 - 第三方应用回调操作

PendingIntent 和 Intent 有什么区别?

从结构上来说,PendingIntent 是 Intent 的包装类,其内部持有一个代表最终意图操作的 Intent。

1、执行进程不同 —— PendingIntent 在其他进程执行: Intent 通常会在创建进程中执行,而 PendingIntent 通常不会在创建进程中执行;
2、执行时间不同 —— PendingIntent 会延迟执行: Intent 通常会立即执行,而 PendingIntent 通常会延迟执行,延迟到其他进程完成任务后再执行,甚至延迟到创建进程消亡后。例如,在 场景 1 - 系统通知消息的点击操作 中,即使发送系统通知消息的进程已经消亡了,依然不妨碍二级 Intent 的跳转;
3、执行身份不同 —— PendingIntent 支持授权: PendingIntent 内部持有授权信息,支持其他应用以当前应用的身份执行,这有利于避免嵌套 Intent 存在的安全隐患。

PendingIntent 的使用方法

启动组件:

// 启动 Activity
PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)
// 启动 Service
PendingIntent.Service(Context context, int requestCode, Intent intent, int flags)
// 发送广播
PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags)
PendingIntent 的 4 个参数:

1、context: 当前应用的上下文,PendingIntent 将从中抽取授权信息;
2、requestCode: PendingIntent 的请求码,与 Intent 的请求码类似;
3、intent: 需要跳转的包装intent;
4、flag: PendingIntent标记位

PendingIntent标记位

FLAG_IMMUTABLE:不可变标记位,将约束外部应用消费 PendingIntent 修改其中的 Intent;
FLAG_MUTABLE:可变标记位,不约束外部应用消费 PendingIntent 修改其中的 Intent;
FLAG_UPDATE_CURRENT:如果系统中已经存在相同的 PendingIntent,那么将保留原有 PendingIntent 对象,而更新其中的 Intent。即使不可变 PendingIntent,依然可以在当前应用更新;
FLAG_CANCEL_CURRENT:如果系统中已经存在相同的 PendingIntent,那么将先取消原有的 PendingIntent,并重新创建新的 PendingIntent。
FLAG_NO_CREATE:如果系统中已经存在相同的 PendingIntent,那么不会重新创建,而是直接返回 null;
FLAG_ONE_SHOT:一次有效标记位,PendingIntent 被消费后不支持重复消费,即只能使用一次。

PendingIntent 可变性是一种对外部应用消费行为的约束机制,通过标记位 FLAG_MUTABLE 和 FLAG_IMMUTABLE 控制 PendingIntent 可变或不可变。可变性意味着在消费 PendingIntent 时,可以针对其中包装的 Intent 进行修改。强烈建议在创建 PendingIntent 时使用 FLAG_IMMUTABLE。

完整使用示例:
            val intent = Intent()
            intent.action = "xxxaction"
            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
            var flag = PendingIntent.FLAG_UPDATE_CURRENT
            if (android.os.Build.VERSION.SDK_INT >= 31) {
                flag = flag or PendingIntent.FLAG_IMMUTABLE
            }
            PendingIntent.getActivity(
                context,
                appWidgetId,
                intent,
                flag
            )
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容