对于 Intent 大家肯定都不陌生,今天我们聊一聊它的一个近亲:PendingIntent
官方对其描述为:
A description of an Intent and target action to perform with it.
那么问题来了:
- PendingIntent 仅仅是对 Intent 的一个封装吗?
- 如果1 不是,那么为什么 PendingIntent与 Intent 有何不同,它的定位是什么样的呢?
- 对于 2 的回答,如果从源码侧佐证?
更多问答 >>
-
2021-05-28 00:29
-
每日一问 | Dialog 的构造方法的 context 必须传入 Activity吗?
2021-07-11 22:06 -
2021-07-11 22:06
-
每日一问 | 我们经常说到的 Android 脱糖指的是什么?
2021-07-11 22:06 -
每日一问 | ViewModel 在什么情况下的「销毁重建」能够对数据进行无缝恢复?
2021-08-25 18:11 -
每日一问 | view.requestLayout如果在灭屏或者切home之后调用会怎么样?
2021-05-06 00:16 -
2021-05-06 00:16
-
每日一问 | 听说你做过内存优化 之 Bitmap内存占用到底在哪?
2021-04-19 23:40 -
2021-04-08 00:25
-
每日一问 | mipmap vs drawable,傻傻分不清楚?
2021-03-30 21:14
先看一下它们各自常见的使用场景:
Intent:startActivity、sendBroadcast、startService;
PendingIntent:AlarmManager、Notification/NotificationManager、RemoteViews/AppWidgetManager;
直接创建Intent通常是在启动Activity、发广播、启动Service的时候。
PendingIntent相信大家也都接触过,在使用AlarmManager创建定时任务,或者给Notification、RemoteViews设置点击事件时都会用到。对于上面Intent那三个使用场景,PendingIntent也有对应的静态方法:getActivity
、getBroadcast
、getService
,它们的作用分别是(在触发时):startActivity、sendBroadcast、startService。既然PendingIntent跟Intent的功能看起来都差不多,那为什么还需要它呢?有什么是直接使用Intent不能做到的?
emmmm,其实它们之间最大的区别,就是:在创建PendingIntent对象时是跟system_process(系统服务进程,AMS、PMS、WMS都在这个进程)有互动的,看这张图:(建议点开放大看)getIntentSender
方法创建一个对应的PendingIntentRecord实例,而那些从App传过来的参数,都会保存在PendingIntentRecord.key
里面,最后会把PendingIntentRecord实例add
到mIntentSenderRecords
中并返回。当我们拿到PendingIntent对象之后,它里面的mTarget
已经初始化完成了,也就是一个IIntentSender(AIDL接口)的Proxy的引用,这就跟之前 说到的ActivityClientRecord与ActivityRecord的关系类似。一旦我们调用PendingIntent.send
,【系统服务进程】那边对应的PendingIntentRecord实例的send
方法就会被调用,它会根据type
(PendingIntent那几个静态方法getActivity
、getBroadcast
等,已经帮我们选择好了Type,比如getActivity
的type
是INTENT_SENDER_ACTIVITY,getService
是INTENT_SENDER_SERVICE)来作出不同的动作。看到那个PendingIntentRecord的内部类Key了吗,它里面的requestIntent
,就是我们一开始往PendingIntent传的那个Intent!在startActivity
或sendBroadcast
、startService
的时候,它就派上用场了!可能有同学已经想到了,因为PendingIntent的相关数据都保存在【系统服务进程】,那么就算创建这个对象的进程已经被kill了,只要这个PendingIntent对象还存在,那它还是能够起到作用的。
为什么会说创建PendingIntent对象的进程被kill,PendingIntent对象还能存在呢?别忘了,PendingIntent是实现了Parcelable的,也就是可以跨进程传输。比如我们常见的:给Notification设置点击事件,Notification就会带着PendingIntent一起被传过NotificationManager那边,最终放到com.android.systemui
进程里,当通知被点击的时候,就会触发它的send
方法。总结:
如果把startActivity(Intent)
、sendBroadcast(Intent)
、startService(Intent)
比作火药的话,那PendingIntent就是能随时引燃这些火药的引线,而点火这个动作,就是它的send
方法。最大的作用应该是添加了一个type属性,然后就知道了这个intent是干嘛的,启动Activity,service还是发广播,不然,当初的intent是判断不出它是干嘛用的 ...查看更多
最大的作用应该是添加了一个type属性,然后就知道了这个intent是干嘛的,启动Activity,service还是发广播,不然,当初的intent是判断不出它是干嘛用的
👍
补充个:https://www.jianshu.com/p/6f66fd5cac20
哈哈哈,这篇文章前段时间在公众号上也看到过,但是当时没有认真看,现在都完全忘掉了😭多谢鸿神提醒,学到了👍🏻
慢慢养成每天来这里蹲洋神和缘神的问答,感觉都是一些刁钻的问题。不过最重要的可能不是问题本身,而是探究的过程能学到很多东西,爱了爱了~
哈哈,我负责问,回答靠小缘和大家~~ 一起学习进步。
别这样,我是弟弟
鸿洋是扔无线吗?我一直感觉是
想问一下,PendingIntent 的 send 方法是何时触发的?
没有特定的时机,完全是看你相关功能的代码怎么写,比如Notification,你在创建notification的时候传了一个pendingIntent进去,那它的send方法就是点击这条notific ...查看更多
没有特定的时机,完全是看你相关功能的代码怎么写,比如Notification,你在创建notification的时候传了一个pendingIntent进去,那它的send方法就是点击这条notification的时候触发。
感谢!
1、PendingIntent是对Intent的包装
2、注意用在通知栏,闹钟之类的,应用A将Intent包装城PendingIntent,传递给系统或者其他应用B,在合适的时机,应用B将PendingIntent里面的Intent发送给应用A或者应用C,这样就可以在合适的时机(比如点击通知栏消息)收到应用A发送的Intent,用来启动Activity、Service等Android组件。