Intent详解

Intent意为意图,是Android程序中各组件之间进行交互的一种重要方式,是对要执行的操作的抽象描述,经常用来启动Activity、启动service与后台服务沟通,也可以broadcastIntent发送给感兴趣的broadcastreceiver组件。下面对Intent的具体用法作以介绍。

一、Intent Structure

Intent有以下几个基本属性:

(1)action--是指Intent将要完成的动作,可以是一段字符串常量。可以使用系统定义的,也可以自己定义,一般来说, 自定义的action应该以application的包名作为前缀, 然后附加特定的大写字符串,比如"com.example.activitytest.ACTION_START",可以使用setAction()方法设定(2)action,getAction()方法获取action,但每个Intent只允许存在一个action。

data--用于指定当前Intent正在操作的数据,经常与action配合使用,这些数据通常是由字符串经过Uri.parse()方法解析出来的uri对象。并且一个intent只允许有一个data。举个例子:

Intent intent=new Intent(Intent.ACTION_VIEW);//Android内置Action

intent.setData(Uri.parse("http://www.baidu.com"));

startActivity(intent);

就会调用系统浏览器打开百度主页。 另外,我们还可以在<intent-filter>标签中配置<data>标签,用于精确地指出当前活动能够响应什么类型的数据,<data>标签主要可以配置以下内容:

1、android:scheme 用于指定数据的协议部分,如上面的http部分

2、android:host 用于指定数据的主机部分,如www.baidu.com

3、android:port 用于指定数据的端口部分,一般在主机名之后

4、android:path 用于指定主机名和端口之后的部分,如网址中跟在域名之后的内容

5、android:mimeType 用于指定可以处理的数据类型,允许使用通配符的方式进行指定

只有<data>标签中指定的内容和Intent中携带的data完全一致时,当前活动在可以响应该intent

(3)category--这一属性也是一个字符串,给出了关于action操作的附加信息。intent可以有任意多个category。用于指定目标组件需要满足的额外条件。可以使用addCategory()方法为intent添加category属性,getCategories()用于获取intent中封装的所有category。Intent类中有一些预定义的部分category:

CATEGORY_HOME:表示目标activity必须是一个显示homescreen的activity

CATEGORY_LAUNCHER--表示目标activity可以作为task栈中的初始activity,常与ACTION_MAIN配合使用

CATEGORY_GADGET--表示目标activity可以被作为另一个activity的一部分嵌入

(4)Type--Type属性显示指定intent的数据类型(MIME),一般intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。

(5)Component--这一属性指定intent的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。可以使用setComponent(ComponentNamecomp)设置该intent的component属性。比如:

ComponentName comp =new ComponentName(FirstActivity。this,SecondActivity。class);
Intent intent = newIntent();
intent.setComponent(comp);

以上创建intent的方式等同于我们日常用的Intent intent = newIntent(FirstActivity.this,SecondActivity.class);

(6)Extra--通过Intent启动一个component时, 经常需要携带一些额外的数据过去。携带数据需要调用Intent的putExtra()方法, 该方法存在多个重载方法, 可用于携带基本数据类型及其数组, String类型及其数组,  Serializable类型及其数组,Parcelable类型及其数组, Bundle类型等。Serializable和Parcelable类型代表一个可序列化的对象, Bundle与Map类似,可用于存储键值对。

(7)Flag--flag属性是一个int值, 用于通知android系统如何启动目标activity,或者启动目标activity之后应该采取怎样的后续操作。所有的flag都在Intent类中定义, 部分常用flag如下:
FLAG_ACTIVITY_NEW_TASK--通知系统将目标activity作为一个新task的初始activity;
FLAG_ACTIVITY_NO_HISTORY--通知系统不要将目标activity放入历史栈中;
FLAG_FROM_BACKGROUND--通知系统这个Intent来源于后台操作, 而非用户的直接选择。

二、Intent与Intent-filter

intent-filter即为intent过滤器。这里先说一下intent的两大类型;显式意图和隐式意图。
显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。如上面介绍component时举得例子中intent的构造方式就是显式意图。
隐式意图:没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。
而对于没有明确指定组件名的隐式意图,android系统是怎样找到最适合的组件呢?这里就用到了intent-filter。
intentfilter负责过滤掉组件无法响应处理的intent,而且intentfilter只会过滤隐式intent,显式intent会直接传给目标组件,每个Android组件可以有多个intentfilter,他们彼此之间是独立的,一般情况下,intentfilter是声明在AndroidManifest.xml文件中的,但是用于过滤广播的intentfilter可以在Java代码中创建。

intentfilter的过滤功能是通过对其Action,Data以及Category字段进行监测:
(1)检查Action
前面说过,一个intent只有一个Action,但是一个intentfilter可以拥有多个Action,即目标intent的Action只要符合intentfilter多个Action中的一个,即表示Action验证通过,同样,若是intentfilter中没有设置任何Action,则任何Action都无法与之匹配,如果intent没有设置Action,则凡是设置了Action的intentfilter都可以通过验证。
(2)检查Data
与Action一样,在intentfilter中,Data部分也可以拥有多个或者没有。对Data的监测主要是对Data的URI和数据类型这两部分进行的,规则很简单,就是intent和intentfilter的 URI和数据类型都相同时才能通过检查。
(3)检查Category
与上面两个不同,对于Category,intent和intentfilter都可以拥有多个。只有Intent中的所有Category都能匹配到Intentfilter中的Category,Intent才能通过检查。也就是说,如果Intent中的Category集合是Intentfilter中Category的集合的子集时,Intent才能通过检查。如果Intent中没有设置Category,则它能通过所有Intentfilter的Category检查。 如果一个Intent能够通过不止一个组件的Intentfilter,用户可能会被问那个组件被激活。如果没有目标找到,会产生一个异常。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值