Intent是信息的载体,用它可以去请求组件做相应的操作,Intent促进了组件之间的交互,做为消息的载体,去指导组件做出相应的行为,Intent可以携带数据,传递给Activity/Service/BroadcastReceiver。
- 启动Activity。Activity可以简单的理解为手机屏幕中的一个页面,你可以通过将Intent传入startActivity方法来启动一个Activity的实例,也就是一个页面,同时,Intent也可以携带数据,传递给新的Activity。如果想要获取新建的Activity执行结果,可以通过onActivityResult()方法去启动Activity。
- 启动Service。Service是一个不呈现交互画面的后台执行操作组件,可以通过将Intent穿入startService()方法来启动一个Service来启动服务。
- 传递广播BroadCast。广播是任何应用都可以接收到的消息,通过将Intent传递给 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast()方法,可以将广播传递接收方。
一、Intent类型
Intent分为两种类型,显式和隐式。
- 显式Intent,可以通过类名来找到相应的组件,在应用中用显式Intent去启动一个组件,通常是因为我们知道这个组件(Activity或者Service)的名字
- 隐式Intent,不指定具体的组件,但是它会声明将要执行的操作,从而匹配到相应的组件。最简单的Android中调用系统拨号页面准备打电话的操作,就是隐式Intent。
使用隐式Intent的时候,系统通过将Intent对象中的IntentFilter与组件在AndroidManifest.xml或者代码中动态声明的IntentFilter进行比较,从而找到要启动的相应组件。如果组件的IntentFilter与Intent中的IntentFilter正好匹配,系统就会启动该组件,并把Intent传递给它。如果有多个组件同时匹配到了,系统则会弹出一个选择框,让用户选择使用哪个应用去处理这个Intent
Intent能够包含的属性有Component、Action、Data、Category、Extras、Flags。
1、隐式Intent
在AndroidManifest.xml文件中使用**标签为组件设置一个或者多个过滤器**。每一个过滤器基于Action、Data、Category来指定自身可以处理的Intent类型。如果隐式Intent的能够匹配到用户设置的其中一个过滤器,系统才能唤起这个应用相应的组件并将Intent传递给这个组件。
每一个过滤器是在AndroidManifest.xml使用标签来定义的,嵌套在组件标签中,例如、标签。在标签中,用户可以使用一下三个属性中的一个或者多个来指定可以接受的Intent。
- ,在这个属性中,声明该组件可以执行的操作。该值必须是关于操作的一个字符串,并不是类常量
- ,使用一个或者多个数据URI(scheme、host、port、path等等)和数据的MIME类型来指定接受的数据类型
- ,声明接受的Intent类型
Activity组件要接受隐式Intent,它必须有一个<category>属性为CATEGORY_DEFAULT的过滤器
,因为startActivity()和startActivityForResult()方法处理Intent时候,默认的认为接受组件有一个属性为CATEGORY_DEFAULT的过滤器。如果一个Activity组件不声明这样一个过滤器,它就接收不到隐式Intent。
2、Intent匹配规则
当发送一个隐式Intent后,系统会将它与设备中的每一个组件的过滤器进行匹配,匹配属性有Action、Category、Data三个,需要这三个属性都匹配成功才能唤起相应的组件。
2.1、Action匹配规则
一个过滤器可以不声明Action属性也可以声明多个Action属性
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
...
</intent-filter>
隐式Intent中的Action属性,与组件中的某一个过滤器的Action能够匹配(如果一个过滤器声明了多个Action属性,只需要匹配其中一个就行),那么就算是匹配成功。
如果过滤器没有声明Action属性,那么只有没有设置Action属性的隐式Intent才能匹配成功。
2.2、Category匹配规则
一个过滤器可以不声明Category属性也可以声明多个Category属性
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
...
</intent-filter>
隐式Intent中声明的Category必须全部能够与某一个过滤器中的Category匹配才算匹配成功。比如说一个Category属性设为CATEGORY_BROWSABLE的隐式Intent也可以通过上面的过滤器,也就是说,过滤器的Category属性内容必须是大于或者等于隐式Intent的Category属性时候,隐式Intent才能匹配成功。
如果一个隐式Intent没有设置Category属性,那么它可以通过任何一个过滤器的Category匹配。
2.3、Data匹配规则
一个过滤器可以不声明Data属性也可以声明多个Data属性
<intent-filter>
<data android:mimeType="video/mpeg" android:scheme="http" ... />
<data android:mimeType="audio/mpeg" android:scheme="http" ... />
...
</intent-filter>
每个Data属性都可以指定数据的URI结构和数据MIME类型。URI包括scheme、host、port 和path四个部分,host和port合起来也成authority(host:port)部分。
在URI中,每个组成部分都是可选的,但是有线性的依赖关系
- 如果没有scheme部分,那么host部分会被忽略
- 如果没有host部分,那么port部分会被忽略
- 如果host部分和port部分都没有,那么path部分会被忽略
当进行URI匹配时候,并不是比较全部,而是局部对比,以下是URI匹配规则。
- 如果一个URI仅声明了scheme部分,那么所有拥有与其相同的scheme的URI都会通过匹配,其他部分不做匹配
- 如果一个URI声明了scheme部分和authority部分,那么拥有与其相同scheme和authority的URI才能匹配成功,path部分不做匹配
- 如果一个URI所有的部分都声明了,那么只有所有部分都相同的URI才能匹配成功
Data匹配时候,MIME类型和URI两者都会进行匹配,匹配规则如下:
- 如果过滤器未声明URI和MIME类型,则只有不含URI和MIME类型的隐形Intent才能匹配成功
- 如果过滤器中声明URI但是未声明MIME类型(也不能从URI中分析出MIME类型),则只有URI与过滤器URI相同且不包含IME类型的隐式Intent才能匹配成功
- 如果过滤器声明MIME类型但是未声明URI,只有包含相同MIME类型但是不包含URI的隐式Intent才能匹配成功
- 如果过滤器声明了URI和MIME类型(既可以是直接设置,也可以是从URI分析出来),只有包含相同的URI和MIME类型的隐式Intent才能匹配成功
进行匹配时候必须以过滤器为单位进行匹配,不能跨过滤器匹配。如果一个过滤器声明了多个Action、Category、Data,隐式Intent包含的Action、Category、Data都能在过滤器中匹配到相应的属性即可,也就是说过滤器中声明的属性是大于或者等于Intent中包含的属性,Intent才能匹配成功