关于intentFiltger的匹配原则,action和category就不具体描述了,相信大家也有基本的了解的,就概括说一下就行了,这篇文章主要讲述data的匹配原则,当然是以隐式跳转的主题讲解的。
1. action的匹配原则
action的匹配原则要求Intent中的action存在并且必须和过滤器规则中其中一个action相同,另外,action区分大小写。否则匹配失败。
2. category匹配原则
(1)如果不存在category,系统默认使用android:intent.category.DEFAULT,隐式跳转除外。如果要使用隐式跳转,必须在intent-filter里边制定这个属性。
(2) 如果存在,intent跳转中一旦有category,不管有几个,每个都需要能够和过滤规则中的任何一个category相同。使用addcategroy方法。可以多个category和intent-filter中的一个相同。
3. 说下action和category的不同点吧
action:intent中必须存在一个action,并且必须有一个action和过滤规则中的action相同。
category:intent中可以不存在category,但是一旦存在,那么所有的category都必须和过滤规则中的其中一个category相同。
————————————————我是分割线—————————————
好了 下边进入主题。data的匹配原则。
1. 先来看下data的用法
<data android:scheme="String"
android:host="String"
android:path="String"
android:pathPattern="String"
android:pathPrefix="String"
android:mimeType="String"></data>
data由两部分组成,mimeType和URI组成。mimeType代表媒体类型,比如image/aaa.jpg等。URI表示路径。下边来讲解下每个数据的含义。
(1) Scheme:URI模式,比如http、filem、content等,如果URI中没有制定Scheme,那么整个URI的其他参数无效,这也就意味着整个URI无效。
(2) Host:URI的主机名,比如www./baidu.com,如果host为制定,整个URI中其他的参数无效,这也就意味着整个URI无效。
(3) Port:URI中的的端口号,比如80端口,仅当scheme和host参数制定的时候,port参数才是有意义的。
(4) path:表示完成的路径信息。
(5) pathPattern:也表示完成的路径信息,但他可以包含通配符“ * ”,* 表示 0个或者多个任意字符,需要注意的是,由于正则的规范,如果想表示真实的字符,要携程\, \要写成\\,
(6) pathPrefix:表示路径的前缀信息。
2. 分情况说明下匹配原则
(1) 代码如下:
<intent-filter>
<data android:mimeType="image/*"
...
</intent-filter>
这种规则指定了媒体类型为所有类型的图片,那么intent中的mimeType必须为image/*才能匹配,这种情况下规律虽然没有指定URI,但是却又默认值,URI的默认值是content和file。也就是说虽然没有指定URI,但是intent的URI部分的scheme必须为content和file才能匹配。也可以这样写:
intent.setDataAndType(Uri.parse("file://abc"), "image/aaa");
这里需要注意的是必须调用setDataAndType,不能先调用setData然后调用setType,这两个方法会清除对方的值,来看下源码:
public Intent setData(Uri data) {
mData = data;
mType = null;
return this;
}
public Intent setType(String type) {
mData = null;
mType = type;
return this;
}
setData会把mimeType置空,setType会把URI置空。
(2) 代码如下:
<intent-filter>
<data android:scheme="http" android:mimeType="video/aaa" ...></data>
<data android:scheme="http" android:mimeType="video/bbb" ...></data>
</intent-filter>
剩下的我想你们应该也会写了,我就不写了。
(3) 写两种代码,作用其实是一样的。
①
<intent-filter>
<data android:scheme="http" android:mimeType="video/aaa" ></data>
...
</intent-filter>
②
<intent-filter>
<data android:scheme="http" ></data>
<data android:mimeType="video/aaa" ></data>
...
</intent-filter>
————————————————我是分割线—————————————
好了,关于intentFiltger的匹配原则就先说到这里,相信大家已经有了基本的认识了,来说写题外话吧。关于Activity跳转到Service或者BroadCastReceiver同样可以使用隐式跳转,不过系统对于启动Ssrvice的建议还是使用显示跳转方法来启动服务。
我再啰嗦一点哈,你们不要打我。
PS:这点很重要
PS:这点很重要
PS:这点很重要
重要的事情说三遍。
当我们使用隐式跳转启动一个Activity的时候,可以做一下判断,看是否有Activity能匹配我们的隐式Intent.如果不能就会出现ActivityNotFoundException错误了。判断方法有两种,如果找不到匹配的Activity,则返回null:
1. PackageManager.resolveActivity():
使用PackageManager的resolveActivity方法,并且PackageManager还提供了queryIntentActivites方法,这个方法和resolveActivity不同的是,它不是返回的最佳的Activity,而是返回了所有匹配成功的Activity。源码:
public abstract List<ResolveInfo> queryIntentActivities(Intent intent, int flags);
public abstract ResolveInfo resolveActivity(Intent intent, int flags);
第一个参数比较好理解,第二个参数需要注意,我们需要使用MATCH_DEFAULT_ONLY这个标记位,它的含义是陪陪那些在intent-filter中生命了category android:name="android.intent.category.DEFAULT"这个category的Activity,使用这个标记位的意义在于,只要上边两个方法不返回null,那么startActivity一定可以成功,如果不用这个标记位,那就可以吧intent-filter中category不含DEFAULT的那些Activity匹配出来,从而导致startActivity可能失败,因为不包含DEFAULT这个category的Activity是无法接收隐式Intent的,在action和category中,有一类action和category比较重要,也是大家最常见的:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
他们表明这是一个入口Activity并且出现在系统的应用列表中,少了任何一个都没有实际的意义,也无法出现在系统的应用列表中,另外针对Service和BroadCastReceiver,PackageManager同样提供了类似的方法获取成功匹配的组件信息。