关于Intent你知多少?

什么是Intent?

Intent是一个消息传递对象,可以使用它来启动其它应用组件。Intent使组件之间通信更加便利,主要用于以下三点:

启动Activity:

可以将intent作为参数调用Context.startActivity(intent)方法启动一个Activity。此时该Intent对象描述了将要启动的目标Activity名称及相关数据信息。同时还可以调用startActivityForResult()方法回传信息。

启动Service:

Service是一个常用于在后台执行操作的组件。可以使用Context.startService(intent)在后台启动一个Service。同样的使用bindService(intent)也需要用到Intent参数。

发送Broadcast:

Broadcast是一种可以被应用程序截获的广播机制。可以通过调用sendBroadcast(intent),sendOrderedBroadcast(intent),sendStickyBroadcast(intent)方法发送一条广播。

可以看到,四大组件中的Activity, Service, Broadcast的启动或发送都需要用到Intent。
Intent的类型

显示Intent:指按名称(完全限定类名)指定要启动的组件。通常在启动自己编写的组件时需要使用显示Intent。

隐式Intent:指不指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它。

创建隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件。 如果 Intent 与 Intent 过滤器匹配,则系统将启动该组件,并向其传递 Intent 对象。 如果多个 Intent 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。
Intent 过滤器是应用清单文件中的一个表达式,它指定该组件要接收的 Intent 类型。 例如,通过为 Activity 声明 Intent 过滤器,您可以使其他应用能够直接使用某一特定类型的 Intent 启动 Activity。同样,如果您没有为 Activity 声明任何 Intent 过滤器,则 Activity 只能通过显式 Intent 启动。
注意:为了确保应用的安全性,启动Service时,请始终使用显示Intent,且不要为服务声明Intent过滤器。使用隐式Intent启动服务存在安全隐患,因为您无法确定哪些服务将响应Intent,且用户无法看到哪些服务已经启动。从Android5.0(API 21)开始,如果使用隐式Intent调用bingService(),系统会引发异常。

Intent包含哪些信息?

Intent的源码中定义了如下关键属性:

private String mAction;
private Uri mData;
private String mType;
private String mPackage;
private ComponentName mComponent;
private int mFlags;
private ArraySet<String> mCategories;
private Bundle mExtras;
private Rect mSourceBounds;
private Intent mSelector;
private ClipData mClipData;
private int mContentUserHint = UserHandle.USER_CURRENT;

Action 操作
指定要执行的通用操作的字符串。对于广播 Intent,这是指已发生且正在报告的操作。操作在很大程度上决定了其余 Intent 的构成,特别是数据和 extra 中包含的内容。一些用于启动Activity的常见操作:
ACTION_VIEW:如果有一些某项 Activity 可向用户显示的信息(例如,要使用图库应用查看的照片;或者要使用地图应用查看的地址),可使用 Intent 将此操作与 startActivity() 结合使用。
ACTION_SEND:也称为“共享”Intent。如果有一些用户可通过其他应用(例如,电子邮件应用或社交共享应用)共享的数据,则应使用Intent将此操作与 startActivity() 结合使用。

Data 数据
引用待操作数据和/或该数据 MIME 类型的 URI(Uri 对象)。提供的数据类型通常由 Intent 的操作决定。例如,如果操作是 ACTION_EDIT,则数据应包含待编辑文档的 URI。 创建 Intent 时,除了指定 URI 以外,指定数据类型(其 MIME 类型)也很重要。

ComponentName 组件名称
构建显示Intent的必要信息。如果没有ComponentName,则表示Intent是隐式的。

Type 类别
一个包含应处理 Intent 组件类型的附加信息的字符串。 您可以将任意数量的类别描述放入一个 Intent 中,但大多数 Intent 均不需要类别。 以下是一些常见类别:
CATEGORY_BROWSABLE:目标Activity允许本身通过网络浏览器启动,以显示链接引用的数据,如图像或电子邮件。
CATEGORY_LAUNCHER:该Activity是任务的初始Activity,在系统的应用启动器中列出。

Extra
用于携带完成请求操作所需的附加信息的键值对。正如某些操作使用特定类型的数据 URI 一样,有些操作也使用特定的 extra。
可以使用各种 putExtra() 方法添加 extra 数据,每种方法均接受两个参数:键名和值。您还可以创建一个包含所有 extra 数据的 Bundle 对象,然后使用 putExtras() 将Bundle 插入 Intent 中。

Intent可以传递Bitmap吗?

查看Intent的源码中,有一个putExtra(String name, byte[] value)方法:

public Intent putExtra(String name, byte[] value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putByteArray(name, value);
return this;
}
可以将Bitmap转化成byte[]进行传递。经测试intent是可以传递bitmap的。

但是,在测试过程中发现,传递的一张500多k的图片是出错了

JavaBinder: !!! FAILED BINDER TRANSACTION !!!
显然,是传输的图片过大,超出了Binder传输的限制了。因为启动另一个Activity的过程中,需要与AMS进程进行Binder通信。(关于Binder通信机制下次详细介绍)

Binder通信过程中,会发生一次内存拷贝,显示,传输的数据越小效率就越高。因此,不建议使用Intent传递比较大的数据。

Intent和PendingIntent的区别

Intent 是及时启动,intent 随所在的activity 消失而消失。

PendingIntent这个类用于处理即将发生的事情。比如在通知Notification中用于跳转页面,但不是马上跳转。

Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,而Pendingintent,一般用在 Notification上,可以理解为延迟执行的intent,PendingIntent是对Intent一个包装。


本文原创发布于公众号《Android面试专栏》,欢迎搜索关注!也欢迎大家留言投稿!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容