Intent Filter
一个Intent
过滤器就是一个IntentFilter
类的实例。Android
系统在启动一个组件之前需要通过Intent
对象与该组件的过滤器进行匹配,只有通过匹配该组件才能被启动。当然这种情况在使用Intent
隐式启动组件时才会出现。由于显示使用Intent
开启组件会明确的指定要开启的组件的类名,因此不需要匹配就能直接启动组件。那么Intent
对象会怎样与过滤器进行匹配呢?
动作检测:在清单文件的<intent-filter>
标签以<action>
子元素列出动作,例如:
<intent-filter>
<action android:name="com.example.demo.SHOW_CURRENT" />
<action android:name="com.example.demo.SHOW_RECENT" />
<action android:name="com.example.demo.SHOW_PENDING" />
...
</intent-filter>
通过代码可以看出,一个过滤器可以列出不止一个<action>
动作,并且这个<action>
列表不能为空,一个过滤器列表必须至少包含一个<action>
子元素,否则它将阻塞所有的intents
。如果过滤器没有指定动作,没有一个Intent将匹配,所有的Intent都将检测失败,也就意味着没有intent可以通过过滤器。要通过检测,Intent对象中指定的动作必须匹配过滤器动作列表中的一个,如果Intent对象没有指定动作,将自动通过检测。
种类检测:类似的,清单文件的<intent-filter>
标签下的<category>
标签列出种类,例如:
<intent-filter>
<category android:name="android.intent.category.DEFSULT" />
<category android:name="android.intent.category.BROWSABLE" />
...
</intent-filter>
通过代码可以看出,一个过滤器也可以列出不止一个<category>
。一个intent
要通过种类检测,intent
对象中的每个种类都必须在过滤器中找到配对,也就是说,过滤器可以列出额外的种类,但是Intent
对象中的所有种类都必须能在过滤器中找到,只要有一个没在过滤器中找到配对就检测失败!
因此原则上如果一个Intent
对象中种类字段为空,应该总能通种类检测。但是需要注意,Android
对待所有传给context.startActivity(Intent intent)
的隐式Intent
至少包含android.intent.category.DEFAULT
,因此组件要想接收隐式Intent
,其过滤器中必须包含android.intent.category.DEFAULT
这个种类。
数据检测:清单文件中的<intent-filter>
标签的<data>
子标签列出数据,例如
<intent-filter>
<data android:mimeType="video/mpeg" android:scheme="http"... />
<data android:mimeType="image/mpeg" android:scheme="http"... />
...
</intent-filter>
进行数据检测的规则是:过滤器不指定任何的URI
和数据类型时,intent
对象既不包含URI
。也不包含数据类型才能通过检测;过滤器只要指定了URI
或者数据类型,一个intent
对象需要URI
或者数据类型匹配才能通过检测,一个intent
对象既包含URI
也包含数据类型(或者数据类型系统能从URI
推断出来也可以),数据类型只要与过滤器的数据类型之一匹配就通过,且URI
要出现在过滤器中或者有content:
或file:URI
或者没有指定URI
才能通过。换言之,如果过滤器只列出了数据类型,组件假定支持content:
和file:
。考虑过滤器的最通用的情况会发现,如下所示
<data android:mimeType="image/*" />
<data android:scheme="http" android:type="video/*" />
第一个标签告诉Android
这个组件能够从ContentProvider
获取image
数据并显示它,第二个标签告诉Android
系统它能够从网络获取video
数据并显示它。