Intent匹配规则:
针对Intent的隐式调用,需要Intent能够匹配目标组建的IntentFilter过滤信息,包括action,category,data;
只有action、category、data三方都匹配,Intent才算是匹配成功,进而才能打开相应的Component;
一个Component若声明了多个Intent Filter,只需要匹配任意一个Intent Filter
即可启动该组件;
1.action的匹配规则
1)一个Intent Filter中可声明多个action,Intent中的action与其中的任意一个
action在字符串形式上完全相同(区分大小写),action方面就匹配成功;
2)可通过setAction方法为Intent设置action,也可在构造Intent时传入action。
3)隐式Intent必须指定action
,若不指定则匹配总会失败
<intent-filter>
<action android:name="Test" />
</intent-filter>
intent.setAction("Test");
上面的例子匹配失败,因为intent自动添加了一个名为android.intent.category.DEFAULT的category,但是xml过滤器中并没有android.intent.category.DEFAULT,所以二者不匹配,所以xml中只有action是不行的;
<intent-filter>
<action android:name="Test" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
intent.setAction("Test"); //匹配成功,通过setAction方法可以看到intent只能有一个Action
2.category的匹配规则
1)Intent中的category必须是Intent Filter中categoty的子集
才能匹配成功
2)Intent可以不指定category,若Intent中未指定category,系统会自动为它带上“android.intent.category.DEFAULT
;
3)Activity必须
在manifest文件中的Intent Filter声明中带有“android.intent.category.DEFAULT“
;
4)通过addCategory方法为Intent添加category。
例子:
<intent-filter>
<category android:name="Test"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
intent.addCategory("Test"); //匹配失败,因为Action没有匹配成功
<intent-filter>
<action android:name="Test" /> //过滤器中至少要有一个action
<category android:name="Test"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
intent.setAction("Test");
intent.addCategory("Test"); //匹配成功,通过addCategory可以得知一个Intent可以有多个Category
3.data的匹配规则
1)data可进一步分为uri(由scheme、host、port、path | pathPattern | pathPrefix这4部分组成)和mimetype。
Intent的uri可通过setData方法设置,mimetype可通过setType方法设置。
2)同action类似,只要Intent的data只要与Intent Filter中的任一个data声明完全相同,data方面就匹配成功。
3)若Intent Filter的data声明部分未指定uri,则缺省uri为content或file,Intent中的uri的scheme部分需为content或file才能匹配,若要为Intent指定完整的data,必须用setDataAndType方法。
举例:
匹配scheme:
<data android:scheme="abc"/>
intent.setData(Uri.parse("abc://adc"));
匹配scheme,host,port:
<data android:scheme="abc" android:host="www.baidu.com" android:port="80" />
intent.setData(Uri.parse("abc://www.baidu.com:80"));
匹配mimetype:
<data android:mimeType="image/*" />
intent.setDataAndType(Uri.parse("content://adc"),"image/png");
匹配失败会抛出ActivityNotFoundException异常