Intent介绍

1、Intent的作用

Intent中文的译名"意图",它用来完成的组件之间的通信,确切的讲,基本有两个作用:

1、可以启动另外一个组件。 

 2、可以携带少量数据传递给另外一个组件。


基本用例有:启动活动、启动服务、传递广播,不包括contentProvider,它使用Uri的方式来启动。


2、用Intent封装启动意图的好处。

就拿启动活动来说,为什么不直接用startActivity(Class activityClass)的方式,这样更符合正常的思考方式。但是假如你需要传递其它信息,比如附加数据,或者隐式的启动一个组件(不指定具体组件类名),需要通过其它信息来定位,需要多个杂乱的方法来实现,另外是启动其它组件,如果服务、广播也同样需要如此;用Intent的方式提供一致的编程模型,把需要的信息都封装起来,更符合Java封装的特点。


3、Intent类型

Intent分为显式Intent和隐式Intent。

显式Intent:按名称(完全限定类名)指定要启动的组件,通常用来在自己应用中启动组件,这是因为你知道需要启动组件(活动或者服务)的类名。

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


创建显式 Intent 启动 Activity 或服务时,系统将立即启动 Intent 对象中指定的应用组件。

创建隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器(intent-filter)进行比较,从而找到要启动的相应组件。如果 Intent 与 Intent 过滤器匹配,则系统将启动该组件,并将其传递给对象。如果多个 Intent 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。



Intent介绍_第1张图片

图 1. 隐式 Intent 如何通过系统传递以启动其他 Activity 的图解:

[1] Activity A 创建包含操作描述的 Intent,并将其传递给 startActivity()

[2] Android 系统搜索所有应用中与 Intent 匹配的 Intent 过滤器。找到匹配项之后,[3] 该系统通过调用匹配 Activity(Activity B)的 onCreate() 方法并将其传递给Intent,以此启动匹配 Activity,可以通过getIntent()方法获取这个Intent对象。


Intent 过滤器是应用清单文件中的一个表达式,它指定该组件要接收的 Intent 类型。例如,通过为 Activity 声明 Intent 过滤器,您可以使其他应用能够直接使用某一特定类型的 Intent 启动 Activity。同样,如果您没有为 Activity 声明任何 Intent 过滤器,则 Activity 只能通过显式 Intent 启动。


3、Intent属性及intent-filter的配置

Intent根据类型、是否携带数据、启动标志,提供了多种属性设置,分别是:

显式:Component,就好比网红明确指定思聪为老公对象。

隐式:Action、Category、Data、Type,就好比要求是CEO、有钱、180、长的帅等属性。

携带数据:Extra

启动标志:Flag


Component(组件名称):要启动的组件名称。

这是可选项,但也是构建显式 Intent 的一项重要信息,这意味着 Intent 应当仅传递给由组件名称定义的应用组件。如果没有组件名称,则 Intent 是隐式,且系统将根据其他 Intent 信息(例如,以下所述的操作、数据和类别)决定哪个组件应当接收 Intent。因此,如需在应用中启动特定的组件,则应指定该组件的名称。您可以使用目标组件的完全限定类名指定此对象,其中包括应用的软件包名称。如,com.example.ExampleActivity您可以使用setComponent()setClass()setClassName()Intent构造函数设置组件名称。

如:

ComponentName comp = new ComponentName(MainActivity.this,SecondActivity.class);

Intent inent = new Intent();

intent.setComponent(comp);

可以通过构造函数简化为另一种形式:

Intent intent = new Intent(MainActivity.this,SecondActivity.class);

而这方式是最常用的方式,但是往往会忽略了它是用来设置组件名称。


Action(操作)指定要执行的通用操作(例如,“查看”或“选取”)的字符串

您可以使用setAction()Intent构造函数为 Intent 指定操作。

如果定义自己的操作,请确保将应用的软件包名称作为前缀。 例如:staticfinalString ACTION_TIMETRAVEL ="com.example.action.TIMETRAVEL";

对于广播 Intent,这是指已发生且正在报告的操作。操作在很大程度上决定了其余 Intent 的构成,特别是数据和 extra 中包含的内容。因为广播

本身就类似一个全局的监听器,所以它都是使用隐式Intent,通过系统层面向匹配到的接收器发送数据和 extra 中包含的内容。


Data(数据):引用待操作数据和/或该数据 MIME 类型的 URI(Uri 对象)。它虽然也是指数据,但是必须是Uri类型,所以不是传统意义上的数据,不过它依然可以解析为有用的信息,比如是一个URL(网址),如“http://www.google.com”,可以访问网页;可以解析为一个电话号码,如“tel:1234”,可以自动拨号。

创建 Intent 时,除了指定 URI 以外,指定数据类型(其 MIME 类型)往往也很重要。例如,能够显示图像的Activity可能无法播放音频文件,即便 URI 格式十分类似时也是如此。因此,指定数据的 MIME 类型有助于 Android 系统找到接收 Intent 的最佳组件。

要仅设置数据 URI,请调用setData()。要仅设置 MIME 类型,请调用setType()。如有必要,您可以使用setDataAndType() 同时显式设置二者。

若要同时设置 URI 和 MIME 类型,请勿调用setData()setType(),因为它们会互相抵消彼此的值。请始终使用setDataAndType()同时设置 URI 和 MIME 类型。


Category(类别):一个包含应处理 Intent 组件类型的附加信息的字符串。您可以将任意数量的类别描述放入一个 Intent 中,但大多数 Intent 均不需要类别。

以下是一些常见类别:
CATEGORY_BROWSABLE
目标 Activity 允许本身通过 Web 浏览器启动,以显示链接引用的数据,如图像或电子邮件。
CATEGORY_LAUNCHER
该 Activity 是任务的初始 Activity,在系统的应用启动器中列出。

有关类别的完整列表,请参阅 Intent 类描述。

您可以使用 addCategory() 指定类别。

以上列出的这些属性(组件名称、操作、数据和类别)表示 Intent 的既定特征。通过读取这些属性,Android 系统能够解析应当启动哪个应用组件。

但是,Intent 也有可能会一些携带不影响其如何解析为应用组件的信息。Intent 还可以提供:

Extra(附加数据): 携带完成请求操作所需的附加信息的键值对。正如某些操作使用特定类型的数据 URI 一样,有些操作也使用特定的附加数据。

您可以使用各种putExtra()方法添加附加数据,每种方法均接受两个参数:键名和值。您还可以创建一个包含所有附加数据的Bundle对象,然后使用putExtras()Bundle插入Intent中。

例如,使用ACTION_SEND创建用于发送电子邮件的 Intent 时,可以使用EXTRA_EMAIL键指定“目标”收件人,并使用EXTRA_SUBJECT键指定“主题”。

Intent类将为标准化的数据类型指定多个EXTRA_*常量。如需声明自己的附加数据键(对于应用接收的Intent),请确保将应用的软件包名称作为前缀。例如:

static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
Flag(启动标志):Intent类中定义的、充当 Intent 元数据的标志。标志可以指示 Android 系统如何启动 Activity(例如,Activity 应属于哪个 任务),以及启动之后如何处理(例如,它是否属于最近的 Activity 列表)。


intent-filte 配置

要公布应用可以接收哪些隐式 Intent,请在清单文件(AndroidManifest.xml)中使用<intent-filter>元素为每个应用组件声明一个或多个Intent过滤器。每个Intent过滤器均根据 Intent的操作(action)、数据(data)和类别(category)指定自身接受的 Intent 类型。仅当隐式 Intent 可以通过 Intent 过滤器之一传递时,系统才会将该 Intent 传递给应用组件

每个Intent过滤器均由应用清单文件中的<intent-filter>元素定义,并嵌套在相应的应用组件(例如,<activity>元素)中。在<intent-filter>内部,您可以使用以下三个元素中的一个或多个指定要接受的 Intent 类型:

在 android: name 属性中,声明接受的 Intent 操作。该值必须是操作的文本字符串值,而不是类常量。它表示该Intent所要完成的一个抽象动作。 <data /> 使用一个或多个指定数据URI( schemehostportpath 等)各个方面和 MIME 类型的属性,声明接受的数据类型。 在AndroidManifest.xml文件中为组件声明Data、Type属性都是通过该元素,它的格式如下: android:scheme = "" android:host = "" android:port = "" android:path = "" android:pathPrefix = "" android:pathPattern = "" /> 其中scheme、hots、port、path都是属于Uri的属性。 ; 在 android: name 属性中,声明接受的 Intent 类别。该值必须是操作的文本字符串值,而不是类常量。它用于为action增加额外的附加类别信息,一般与action结合使用。 当程序中创建Intent时,该Intent默认启动Category属性值为Intent.CATEGORY_DEFAULT常量的组件,所以在被启动Activity对应的配置元素的元素里面至少还包括如下子元素:

在Androidmanifest.xml中,一个组件下面可以声明0个或多个intent-filter;一个intent-filter下面可以分别声明0个或多个action、category、data子元素。


4、Intent匹配规则

ntent-filter>:如果该组件声明多个intent-filter子元素,只要隐式Intent对象的属性能够匹配其中一个就可以启动该组件;

在intent-filter下面可以声明子元素,必须要通过所有这三项匹配,才能启动该组件。如果有子元素没有声明,则按已声明的子元素去逐一匹配。

因为可以声明多个,但只需要与其中一个匹配,就看作是该属性匹配成功;

同上。

:而data子元素不是值完全相同才算匹配成功,如果data子元素中只指定了android:scheme属性,那么只要Intent对象中data属性的scheme部分与android:scheme属性值相同,既即可启动该组件;如果data子元素中只指定了android:scheme、android:host属性,那么只要Intent对象中data属性的scheme、host部分与android:scheme、android:host属性值相同,即可启动该组件,依次类推。


参考:

1、Google Guide:Intents and Intent Filter

2、疯狂Android讲义:5.1 Intent对象简述 5.2 Intent属性及intent filter配置。

你可能感兴趣的:(Android基础)