第一章-intentFilter的匹配规则

1、序言:

我们知道,启动Activity分为两种,显示调用和隐式调用,二者的区别这里就不多讲了,显示调用需要明确的指定被启动对象的组件信息,包括包名和类名,而隐式意图则不需要明确指定调用信息,原则上一个intent不应该即是显式调用又是隐式调用,如果二者共存的话以显式调用为主,显式调用很简单,这里主要介绍隐式调用,隐式调用需要intent能够匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配将无法启动目标Activity,IntentFilter中的过滤信息有action,category,data,下面是一个过滤规则的实例:

第一章-intentFilter的匹配规则_第1张图片

为了匹配过滤列表,需要同时匹配过滤列表中的action,category,data信息,否则匹配失败,一个过滤列表中的action,category,data可以有多个,所有的action,category,data分别构成不同类别,同一类型的信息共同约束当前类别的匹配过程,只有一个intent同时匹配action类别,category类别,data类别才算是匹配完成,只有完全匹配才能成功启动目标Activity,另外一点,一个Activity钟可以有多个intent-filter,一个intent只要能匹配一组intent-filter即可成功启动Activity

第一章-intentFilter的匹配规则_第2张图片

2、action的匹配规则

action是一个字符串,系统预定了一些action,同时我们也可以在应用中定义自己的action,action的匹配规则是intent中的action必须能够和过滤规则中的action匹配,这里说的匹配是指action的字符串值完全一样
一个过滤规则中的可以有多个action,那么只要intent中的action能够和过滤规则中的任何一个action相同即可匹配成功。需要注意的是,intent如果没有指定action,那么匹配失败。
总结一下,action的匹配要求intent中的action存在且必须和过滤规则中的其中一个action相同,这里需要注意它和category匹配规则的不同,另外,action区分大小写,大小写不同的字符串匹配也会失败

3、category的匹配规则

第一章-intentFilter的匹配规则_第3张图片
4、data匹配规则

data的匹配规则和action有点类似,如果过滤规则中定义了data,那么intent中必须也要定义可匹配的data,在介绍data的匹配规则之前,我们需要来了解一下data的结构,因为data稍微有点复杂

第一章-intentFilter的匹配规则_第4张图片
第一章-intentFilter的匹配规则_第5张图片

  • Scheme:URI的模式,比如http.file.content等,如果URI中没有指定的scheme,那么整个URI的其他参数无效,这也意味着URI无效
  • Host:URI的主机,比如www.google.com,如果host未指定,那么整个URI中的其他参数无效,这也意味着URI无效
  • Port:URI中的端口号,比如80,不过需要指定上面两个才有意义
    第一章-intentFilter的匹配规则_第6张图片

5、过滤规则

介绍完data的数据格式后,我们要说一下data的匹配规则了。前面说到,data的匹配规则和action类似,它也要求Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data.这里的完全匹配是指过滤规则中出现的data部分也出现在了 Intent
中的data中。下面分情况说明。

(1) 如下过滤规则

<intent-filter>
    <data android:mimeType="image/*"/>
    ...
</intent-filter>

这种规则指定了所有类型为图片,那么intent中的mineType属性必须为“image/*”才能匹配,这种情况下虽然过滤规则没有指定URI,但是却有默认值,URI的默认值为content和file,也就是说,虽然没有指定URI,但是Intent中的URI部分的scheme必须为content或者file才能匹配,这点事需要注意的,为了匹配一种的规则我们可以这样写:

intent.setDataAndType(Uri.parse("file://abc"),"image/png");

注意,如果要为Intent指定完整的data,必须调用setDataAndType方法,不能县调用setData在调用setType,因为这两个方法彼此会清除对方的值,这个看源码就比较好理解了,比如setData:

public Intent setData(Uri data) {
    mData = data;
    mType = null;
    return this;
}

可以发现,setData会把类型设置为null,同样的,对方也是.

(2)如下过滤规则

<intent-filter>
        <data android:mimeType="video/mpeg" android:scheme="http" .../>
        <data android:mimeType="audio/mpeg" android:scheme="http" .../>
        ...
</intent-filter>

这种规则指定了两组data规则,且每个data都指出了完整的属性值,既有URI又有mimeType,为了匹配(2)中规则,我们可以写出:

intent.setDataAndType(Uri.parse("http://abc"),"video/png");

或者

intent.setDataAndType(Uri.parse("http://abc"),"audio/png"); 

通过上面的实例,我们应该知道了data的匹配规则,关于data还有一些特殊的情况需要说明一下,这也是它和action不同的地方,如下2种写法,它们的作用是一样的:

<intent-filter >
 <data android:scheme="file" android:host="www.baidu.com"/>
     ...
</intent-filter>

<intent-filter >
   <data android:scheme="file" />
   <data android:host="www.baidu.com"/>
     ...
</intent-filter>

6、总结

第一章-intentFilter的匹配规则_第7张图片

第一章-intentFilter的匹配规则_第8张图片

这二者共同作用是用来标明这是一个入口Activity并且会出现在系统的应用列表中,少了任何一个都没有实际意义,也无法出现在系统的应用列表中,也就是二者缺一不可,另外,针对 Service和BroadcastReceiver,PackageManager同样提供了类似的方法去获取成功匹配的组件信息。

第一章已完结。

你可能感兴趣的:(Android艺术开发阅读)