IntentFilter详解

简介

IntentFilter可以理解为Intent的过滤器,作用是在利用隐式Intent启动组件时过滤掉不匹配的组件,找到能够正确完成任务的组件。一个Intent想要通过IntentFilter,需要完成三项测试:操作测试、数据测试、类别测试。
一个组件可以拥有多个IntentFilter,但只需要通过其中之一即可启动该组件。
IntentFilter既可以在Manifest文件中利用<intent-filter>标签进行静态声明,也可以在代码中创建IntentFilter对象实现动态声明。
Android要求Service始终需要由显式Intent启动,因此不应当为Service组件声明IntentFilter。

操作测试(Action)

要指定接受的 Intent 操作,IntentFilter既可以不声明任何 <action> 元素,也可以声明多个此类元素。

  • Intent中未声明<action>元素,IntentFilter中也未声明<action>元素:无法通过。
  • Intent中声明了<action>元素,IntentFilter中未声明<action>元素:无法通过。
  • Intent中未声明<action>元素,IntentFilter中声明了<action>元素:无条件通过。
  • Intent中声明了<action>元素,IntentFilter中也声明了<action>元素:只要Intent中的任意一个<action>元素与IntentFilter中的<action>元素匹配就能通过测试。

类别测试(Category)

要指定接受的 Intent 类别,IntentFilter既可以不声明任何 <category>元素,也可以声明多个此类元素。

  • Intent中未声明<category>元素,IntentFilter中也未声明<category>元素:系统会自动把CATEGORY_DEFAULT赋给所有隐式Intent,所以无法通过。
  • Intent中声明了<category>元素,IntentFilter中未声明<category>元素:无法通过。
  • Intent中未声明<category>元素,IntentFilter中声明了<category>元素:只要IntentFilter中声明了CATEGORY_DEFAULT就无条件通过,否则不通过。
  • Intent中声明了<category>元素,IntentFilter中也声明了<category>元素:Intent中的<category>元素集是IntentFilter中的<category>元素集的子集就能通过测试。

数据测试(Data)

(1)URL结构与MIME数据类型
标准URL格式:<scheme>://<host>:<port>/<path>
例:content://com.example.project:200/folder/subfolder/etc在此 URI 中,架构是 content,主机是com.example.project,端口是 200,路径是 folder/subfolder/etc。
(2)URL与IntentFilter匹配规则
要指定接受的 Intent 数据, Intent 过滤器既可以不声明任何 <data>元素,也可以声明多个此类元素。
<data>元素声明示例:<data android:mimeType="video/mpeg" android:scheme="http" ... />
每个<data>元素均可指定 URI 结构和数据类型(MIME 媒体类型)。 URI 的每个部分均包含单独的 scheme、host、port 和 path 。
在<data>元素中,上述每个属性均为可选,但存在线性依赖关系:

  • 如果未指定架构,则会忽略主机。
  • 如果未指定主机,则会忽略端口。
  • 如果未指定架构和主机,则会忽略路径。

将 Intent 中的 URI 与过滤器中的 URI 规范进行比较时,它仅与过滤器中包含的部分 URI 进行比较。例如:

  • 如果过滤器仅指定架构,则具有该架构的所有 URI 均与该过滤器匹配。
  • 如果过滤器指定架构和权限,但未指定路径,则具有相同架构和权限的所有 URI 均与该过滤器匹配。
  • 如果过滤器指定架构、权限和路径,则仅具有相同架构、权限和路径的 URI 才会通过过滤器。路径规范可以包含星号通配符 (*),因此仅需部分匹配路径名即可。

(3)数据测试具体规则
数据测试会将 Intent 中的 URI 和 MIME 类型与过滤器中指定的 URI 和 MIME 类型进行比较。 规则如下:

  • 仅当过滤器未指定任何 URI 或 MIME 类型时,不含 URI 和 MIME 类型的 Intent 才会通过测试。
  • 对于包含 URI 但不含 MIME 类型(既未显式声明,也无法通过 URI 推断得出)的 Intent,仅当其 URI 与过滤器的 URI 格式匹配、且过滤器同样未指定 MIME 类型时,才会通过测试。
  • 仅当过滤器列出相同的 MIME 类型且未指定 URI 格式时,包含 MIME 类型、但不含 URI 的 Intent 才会通过测试。
  • 仅当 MIME 类型与过滤器中列出的类型匹配时,同时包含 URI 类型和 MIME 类型(通过显式声明,或可以通过 URI 推断得出)的 Intent 才会通过测试的 MIME 类型部分。 如果 Intent 的 URI 与过滤器中的 URI 匹配,或者如果 Intent 具有 content: 或 file: 抬头的URI 且过滤器未指定 URI,则 Intent 会通过测试的 URI 部分。 换言之,如果过滤器只是列出 MIME 类型,则假定组件支持 content: 和 file: 数据。

简而言之,数据测试以IntentFilter为核心,Intent的数据部分(URL、MIME)只有在IntentFilter的要求之内才能通过。IntentFilter未声明的话,Intent也不能有,否则就无法通过。唯一例外:第四条规则中,同时包含URL(content:或file:抬头)和MIME的Intent,若MIME匹配,且IntentFilter未定义URL的话就能匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值