作为四大组件的枢纽,Intent和IntentFilter起着功不可没的作用,所以有必要好好做个总结。
一、Intent
Intent分为两种类型:显式Intent、隐式Intent
- 显示Intent:指定要启动组件的名称(类的全路径名)
|
|
- 隐式Intent:不指定特定的组件,而是通过设置常规操作,如:
Action、Data、Category
|
|
在构造Intent的时候可以给这个Intent指定这些信息:Component name、Action、Data、Category、Extras、Flags
①Component name:主要是用来指定组件名称,可以通过setComponent()、setClass()、setClassName() 或者直接通过Intent的构造函数来指定组件名称。
示例:
② Action:主要用来指定Intent的动作,可以通过setAction() 来指定Intent的动作。
示例:
Action的种类很多,具体种类可以去官网的Intent类中查看。
③ Data:主要用来指定Intent携带的数据,可以通过setData() 来指定Intent携带的数据。例如上面的例子中就就通过setData 来指定携带了电话号码。
setData()和setType()的注意事项:
当要指定data和type的时候请使setDataAndType(),因为用setData和setType()来分别制定data和type时,setData()和setType()都会清除对方的值。
④ Category:主要用于隐式Intent,用来指定类别,通过addCategory() 来指定类别。主要用途是用来匹配Intent-Filter中的<category> 标签中的元素。后面会在IntentFilter中作详细讲解。
⑤ Extras: 主要用于携带完成请求操作所需的附加信息的键值对,通过putExtra() 方法来存入键值对。
示例:
putExtra() 能存入很多基本数据类型,还可以put对象,通过这个方法就可以完成Activity之间的数据交互。
Flags 见名思意,可以用来携带标志,通过setFlags() 就可以指定所需要的标志。
示例:
能指定的Flags有很多,具体的Flags有哪些可以去官网的Intent类中查看。
二、IntentFilter
IntentFilter是用来过滤Intent的,当用隐式Intent来启动一个Activity的时候,就会匹配Intent携带的信息和intent-filter 中的过滤信息,当这些信息匹配成功则启动Activity。intent-filter 的过滤信息分为三类,分别是:action类、category类、data类。
一个<Activity> 节下面可以包含多个<intent-filter> 节,当一个Intent能匹配任何一个<intent-filter> 中的action类、category类 和 data类 时则匹配成功,此时才能启动目标Activity。
下面是一个Activity中的过滤规则示例:
在这个<Activity>中有两组<intent-filter>,只要一个Intent能匹配其中任意一组<intent-filter>即可。这里的匹配是指需要同时匹配一组中的action类别、categroy类别和data类别。
下面分别详细介绍这三个类别的匹配规则。
1、action 的匹配规则
从上面的例子中可以看出,一个intent-filter中可以有多个action,如果Intent中的action和过滤规则中action的字符串相同(区分大小写),则匹配。如果intent-filter中有多个action,那么只要匹配上过滤规则中的一个action也算匹配成功。如果Intent中没有指定action或则与intent-filter中的action一个也没匹配上,则匹配失败。比如:Intent中action的值为com.tdw.action_1 或 com.tdw.action_2就算匹配成功,如果一个都不相同则匹配失败。
2、category 的匹配规则category 的匹配规则和action的匹配规则有所不同。如果Intent中携带了category,不管有几个category,对于携带的每个category 来说,它必须是过滤规则中已经定义好了的category。但是Intent中也可以没有携带category,如果没有的话也可以匹配成功,因为系统在调用startActivity 或者 startActivityForResult 的时候会默认为Intent加上“android.intent.category.DEFAULT”这个category。与action 不同的是,action 是要求Intent中必须有一个action 且必须能够和过滤规则中的某个action 相同。
3、data的匹配规则
要了解data 的匹配规则首先要了解data 的语法,所以还是先来学习data 的语法。
data 的语法示例:
data 由两部份组成,mimeType和URI。mimeType指媒体类型,比如:image/jpeg 和 video/* 可以分别表示图片和视频。mimeType的媒体类型有很多,具体需要用时可以去查看。而URI中包含的数据就比较多了,URI的结构如下:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
具体示例:content://com.example.project:200/folder/subfolder/ethttp://www.google.com:80/search/info
通过两个具体示例和URI的结构示例对照看就很清楚URI的含义了。
scheme: URI的模式,比如http、file、content等,如果URI中没有指定scheme,那么整个URI的其他参数无效,这也意味着URI无效。
host: URI的主机名,比如:www.google.com,如果host为指定,那么整个URI的其他参数无效,这也意味着着URI无效。
port: URI的端口号,比如:80,仅当URI中指定了scheme和host参数的时候port参数才是有意义的。
path、pathPattern、和pathPrefix: 这三个参数表述路径信息,其中path表示完整的路径信息; pathPattern也表示完整的路径信息,大师它里面可以包含通配符(*), 通配符(*) 表示0个或多个任意字符,需要注意的是,由于正则表达式的规范,如果想表示真实的字符串,那么* 要写成\\* ,\要写成\\\;pathPrefix 表示路径的前缀信息。
data 的匹配规则和action 类似,它也要求Intent中必须含有data 数据,并且data 数据能够完全匹配过滤规则中的某一个data。这里的完全匹配是指过滤规则中出现的data 部分也出现在了Intent中的data 中。
- 示例1:
|
|
这个示例当中,mimeType指定的媒体类型是图片,那么Intent中的mimeType属性也必须为”image/*“才能匹配,这种情况下虽然没有指定URI,但是确是有默认值,URI的默认值为content和file。也就是说,虽然没有指定URI,但是Intent中的URI部分的scheme 必须为content或则file才能匹配。所以Intent中的scheme 可以这么写:
intent.setDataAndType(Uri.parse(“file://abc”),”image/*”)
注意的是:如果要为Intent指定完整的data ,必须用setDataAndType 方法,不能先调用setData 再调用setType ,因为这两个方法在调用时会彼此清除对方的值。
- 示例2:
|
|
这种规则指定了两组data 规则,且每个data 都指定了完整的属性值,既有URI又有mimeType。为了匹配示例2中的规则,可以在写出如下示例:
intent.setDataAndType(Uri.parse(“http://abc"),"video/mpeg“)
或则是
intent.setDataAndType(Uri.parse(“http://abc"),"audio/mpeg“)
- 示例3:12345678910111213<!--第一种--><intent-filter><dataandroid:scheme="file"android:host="www.google.com" />...</intent-filter><!--第二种--><intent-filter><data android:scheme="file" /><data android:host="www.google.com" />...</intent-filter>
这是 data 特殊情况,如上两种写法,作用是一样的。
参考书籍: Android开发艺术探索
参考网站: Android官方文档