1 概述
activity的启动分为隐式和显式两种,要使用隐式的启动,那么intentFilter是非常重要的一个知识点。
这里将讲解intentFilter的匹配规则。
2 基本形式
<activity
android:name="com.tencent.tauth.AuthActivity"
android:launchMode="singleTask"
android:noHistory="true"
android:taskAffinity="com.coohuaclient">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="tencent1101354300"/>
</intent-filter>
</activity>
可以看到,intentFilter中有action,category,以及data这几种形式的信息。
3 action匹配规则
在xml中的intent-filter中可以配置多个action值,在隐式启动的intent中,最多只能指定一个action值,要想隐式启动成功,则必须指定这个action的值,且这个action值必须匹配上xml配置的任意一个值。
值得注意的是,action是区分大小写的。
4 category匹配规则
在隐式启动的intent中,系统都会默认加上android.intent.category.DEFAULT这种category,因此,在xml中也必须指定这种值,这是成功调用的前提条件。category的规则和action不大相同。分为2种情况;
intent中含有category:
那么这些category必须都匹配上xml指定的值。
intent中没有category:
这种情况下,系统会在intent中设置默认的category,也就是android.intent.category.DEFAULT,如果这个值能匹配上xml中指定的,那么也能调用成功。
5 data匹配规则
data的数据相对比较复杂,我们先看看它的完整数据项:
<data
android:mimeType="image/*"
android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
/>
可以看到,data由两部分组成,一部分是mimeType代表了数据的媒体类型,其他的是URI,指定了资源的位置。
看看URI的结构:
://:/[||]
例如:
content://com.baidu.haha:8080/dir/src/text.txt
http://www.baidu.com:80/dir/src/text.txt
上面的两种例子说明了URI的格式对。
这里值得说明的是path,pathPrefix以及pathPattern的区别,path指的是完整的路径,例如上诉例子中path代表“/dir/src/text.txt”,而pathPrefix代表了完整路径的起始部分,可以是/dir也可以是/dir/src,pathPattern则是符合正则表达式的路径,可以用正则表达式来表示路径,从而实现匹配。值得注意的是,pathPattern使用中,如果要表达例如这类在正则表达式中有作用的字符,那么需要进行转义,但是写成“*”是不行的,因为清单文件是一个xml文件,他在被系统读取到内存的时候,会被转义一次,当pathPattern被当作正则表达式的读取的时候又会转义一次,所以这里有两次转义。所以,应该写成“\”,而“\”则要写成”\\”
data如下的两种写法效果一致:
<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 注意事项
使用隐式启动的时候,最好判断一下是否有匹配该隐式intent的activity,否则启动会出错。要判断是否有符合条件的activity有两种方法,一是使用packageManager的resolveActivity方法,一是使用Intent的resolveActivity,如果找不到匹配的就返回null,我们可以根据返回值判断是否有合适的activity。
看看方法:
public ActivityInfo resolveActivityInfo(PackageManager pm, int flags)
这里的flags需要解释一下,我们一般会使用MATCH_DEFAULT_ONLY这个标志位,因为这个标志位代表了,仅仅返回在xml中声明了android.intent.category.DEFAULT的activity,而这是隐式启动成功的前提条件。