内容简介:博客原文:出于对 PendingIntent 的好奇心,翻阅了很多资料。最后发现还是官方文档描述地到位。前三段话读下去已经解决了我的大部分疑惑。整篇读完有种豁然开朗的快感。 等翻译完,开始有点不解自己最初竟然会有总之,对于对 PendingIntent 尚有疑问的同学来说,这文档是真不错。
博客原文: [11月的好奇心] PendingIntent 是啥?为什么很多场景不能直接用 Intent 非要用 PendingIntent?
出于对 PendingIntent 的好奇心,翻阅了很多资料。最后发现还是官方文档描述地到位。前三段话读下去已经解决了我的大部分疑惑。整篇读完有种豁然开朗的快感。 等翻译完,开始有点不解自己最初竟然会有 为什么不直接使用 Intent 代替 PendingIntent? 这样的问题。
总之,对于对 PendingIntent 尚有疑问的同学来说,这文档是真不错。
/** * A description of an Intent and target action to perform with it. Instances * of this class are created with {@link #getActivity}, {@link #getActivities}, * {@link #getBroadcast}, and {@link #getService}; the returned object can be * handed to other applications so that they can perform the action you * described on your behalf at a later time. 复制代码
这里说 PendingIntent
是 Intent
行为的描述类。类似于我们用一个文件句柄,来说明它所对应的文件。 它由这四个方法创建: getActivity
getActivities
getBroadcast
getService
。 它可以被其它应用调用以执行你预先声明的行为。
这里可以这么对比理解: FileDescriptor 用来描述文件 Socket 用来描述网络 PendingIntent 用来描述行为
如果把类名改为 IntentDescriptor
或许会更好理解。
* * <p>By giving a PendingIntent to another application, * you are granting it the right to perform the operation you have specified * as if the other application was yourself (with the same permissions and * identity). As such, you should be careful about how you build the PendingIntent: * almost always, for example, the base Intent you supply should have the component * name explicitly set to one of your own components, to ensure it is ultimately * sent there and nowhere else. * 复制代码
把 PendingIntent
交给其它应用,你就授予了它们进行其所定义的行为的权利。 所以你创建 PendingIntent
一定要格外小心:记住在你定义的 Intent
中加上限制用的包名、类名,以确保它只被你希望的对象使用。
这段是在说,我不仅告诉你你该做啥,连权限也给你了。
这搁在军营中,就是一道虎符啊。所以一定要声明好把虎符具体交到谁的手中,不然会很危险。
* <p>A PendingIntent itself is simply a reference to a token maintained by * the system describing the original data used to retrieve it. This means * that, even if its owning application's process is killed, the * PendingIntent itself will remain usable from other processes that * have been given it. If the creating application later re-retrieves the * same kind of PendingIntent (same operation, same Intent action, data, * categories, and components, and same flags), it will receive a PendingIntent * representing the same token if that is still valid, and can thus call * {@link #cancel} to remove it. * 复制代码
我们现在知道 PendingIntent
其实就是个 IntentDescriptor
行为描述符,但是它存到哪里了呢? maintained by the system ,和文件一样,被系统维护。所以无论创建它的进程是否存在,它都和文件一样,被系统保存在了某个地方。只要你拥有“读取权限”,就能随时获取它。 如果创建 PendingIntent
的程序后来又要获取相同类型的 PendingIntent
(相同的操作、相同的 Intent
action、data、categories、component、flags),那么它会获取到和之前相同的 token, 前提是它仍然有效。此时你可以取消它,如果你希望的话。
* <p>Because of this behavior, it is important to know when two Intents * are considered to be the same for purposes of retrieving a PendingIntent. * A common mistake people make is to create multiple PendingIntent objects * with Intents that only vary in their "extra" contents, expecting to get * a different PendingIntent each time. This does <em>not</em> happen. The * parts of the Intent that are used for matching are the same ones defined * by {@link Intent#filterEquals(Intent) Intent.filterEquals}. If you use two * Intent objects that are equivalent as per * {@link Intent#filterEquals(Intent) Intent.filterEquals}, then you will get * the same PendingIntent for both of them. * 复制代码
这段说,上面说过使用两个相同的 Intent
会获取到同一个 PendingIntent
,那么什么样的 Intent
被认为是相同的呢? 很多人常犯的错误是,认为只改变 Intent#extra
内容就可以获取到不同的 PendingIntent
。 而事实并非如此。 Intent
是否相同通过 Intent.filterEquals
判断。见下图。只有这个方法返回 false
, 才能得到不同的 PendingIntent
。
* <p>There are two typical ways to deal with this. * * <p>If you truly need multiple distinct PendingIntent objects active at * the same time (such as to use as two notifications that are both shown * at the same time), then you will need to ensure there is something that * is different about them to associate them with different PendingIntents. * This may be any of the Intent attributes considered by * {@link Intent#filterEquals(Intent) Intent.filterEquals}, or different * request code integers supplied to {@link #getActivity}, {@link #getActivities}, * {@link #getBroadcast}, or {@link #getService}. * * <p>If you only need one PendingIntent active at a time for any of the * Intents you will use, then you can alternatively use the flags * {@link #FLAG_CANCEL_CURRENT} or {@link #FLAG_UPDATE_CURRENT} to either * cancel or modify whatever current PendingIntent is associated with the * Intent you are supplying. */ 复制代码
这段就比较啰嗦了,简单两句话说明
在某些场景有两种方法来避免获取到相同 PendingIntent
:
- 改变
Intent#filterEquals
中作为判断一句的某个字段 - 获取
PendingIntent
时使用不同的requestCode
如果你有多个不同的 Intent
,但你只需要一个活动的 PendingIntent
。那么你需要通过和它绑定的 Intent
来更新或移除它。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- mac软件:微信双开,一步到位
- vue开发环境配置跨域,一步到位
- 一份运维监控的秘籍!监控不到位,宕机两行泪
- 调整PG分多次调整和一次到位的迁移差别分析
- vuex-stepbystep 经典案例,详细注释一步到位
- 变分自编码器(四):一步到位的聚类方案
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Twenty Lectures on Algorithmic Game Theory
Tim Roughgarden / Cambridge University Press / 2016-8-31 / USD 34.99
Computer science and economics have engaged in a lively interaction over the past fifteen years, resulting in the new field of algorithmic game theory. Many problems that are central to modern compute......一起来看看 《Twenty Lectures on Algorithmic Game Theory》 这本书的介绍吧!