您的位置:首页 > 其它

Intent介绍

2016-10-07 09:25 1581 查看

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
过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。




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 类型:

<action />

在 android:
name 
属性中,声明接受的 Intent 操作。该值必须是操作的文本字符串值,而不是类常量。它表示该Intent所要完成的一个抽象动作。
<
data
/>

使用一个或多个指定数据URI(
scheme
host
port
path
 等)各个方面和 MIME 类型的属性,声明接受的数据类型。
在AndroidManifest.xml文件中为组件声明Data、Type属性都是通过该元素,它的格式如下:
<data android:mimeType = "" 
android:scheme = ""
android:host = ""
android:port = ""
android:path = ""
android:pathPrefix = ""
android:pathPattern = "" />
其中scheme、hots、port、path都是属于Uri的属性。

<category />;

在 android:
name 
属性中,声明接受的 Intent 类别。该值必须是操作的文本字符串值,而不是类常量。它用于为action增加额外的附加类别信息,一般与action结合使用。
当程序中创建Intent时,该Intent默认启动Category属性值为Intent.CATEGORY_DEFAULT常量的组件,所以在被启动Activity对应的配置元素的<intent-filter />元素里面至少还包括如下<category />子元素:
<category android:name="android.intent.category.DEFALUT" />

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

4、Intent匹配规则

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

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

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

<category>:同上。

<data>:而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配置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: