IntentFilter的匹配规则

来源:互联网 发布:linux 查看tomcat内存 编辑:程序博客网 时间:2024/04/28 11:39

隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配将无法启动目标Activity。IntentFilter中的过滤信息有action、category、data。

只有一个Intent同时匹配action类别、category类别、data类别才算完全匹配,只有完全匹配才能成功启动目标Activity。另外一点,一个Activity中可以有多个intent-filter,一个Intent只要能匹配任何一组intent-filter即可成功启动对应的Activity。

<activity    android:name="com.ryg.chapter_1.ThirdActivity"    android:configChanges="screenLayout"    android:label="@string/app_name"    android:launchMode="singleTask"    android:taskAffinity="com.ryg.task1">    <Intent-filter>        <action android:name="com.ryg.charpter_1.c"/>        <action android:name="com.ryg.cahrpter_1.d"/>        <category android:name="com.ryg.category.c"/>        <category android:name="com.ryg.category.d"/>        <data android:mimeType="text/plain"/>    </intent-filter></activity><activity  android:name="ShareActivity">    <intent-filter>        <action android:name="android.intent.action.SEND"/>        <category android:name="android.intent.category.DEFAULT"/>        <data android:mimeType="text/plain"/>    </intent-filter>    <intetn-filter>        <action android:name="android.intent.action.SEND"/>        <action android:name="android.intent.action.SEND_MULTIPLE"/>        <category android:name="android.intent.category.DEFAULT"/>        <data android:mimeType="application/vnd.google.panorama360+jpg"/>        <data android:mimeType="image/*"/>        <data android:mimeType="video/*"/>    </intent-filter></activity>

action 的匹配规则

一个过滤规则中可以有多个action,那么只要Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功。需要注意的是,Intent中如果没有指定action,那么匹配失败。

category的匹配规则

它要求Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。换句话说,Intent中如果出现了category,不管有几个category,对于每个category来说,它必须是过滤规则中已经定义了的category。当然,Intent中可以没有category,如果没有category的话,按照上面的描述,这个Intent仍然可以匹配成功。

data 的匹配规则

如果过滤规则中定义了data,那么Intent中必须也要定义可匹配的data。data由两部分组成,mimeType和URI。mimeType指媒体类型,比如image/jpeg、audio/mpeg4-generic和video/*等,可以表示图片、文本、视频等不同的媒体格式,而URI中包含的数据就比较多了,下面是URI的结构:
://:/[||]
content://com.example.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info

scheme:URI的模式,比如http、file、content等,如果URI中没有指定scheme,那么整个URI的其他参数无效,这也意味着URI是无效的。Host:URI的主机名,比如www.baidu.com,如果host未指定,那么整个URI中的其他参数无效,这也意味着URI是无效的。Port:URI中的端口号,比如80,仅当URI中指定了scheme和host参数的时候port参数才是有意义的。

data的匹配规则,它要求Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data。

<intent-filter>    <data android:mimeType="image/*"/></intent-filter>这种情况下虽然过滤规则没有指定URI,但是却有默认值,URI的默认值为content和file.

如果要为Intent指定完整的data,必须调用setDataAndType方法,不能先调用setData()方法再调用setType()方法,因为这两个方法彼此会清除对方的值。
intent.setDataAndType(Uri.parse(“file://abc”),”image/*”);

最后,当我们通过隐私方式启动一个Activity的时候,可以做一下判断,看是否有Activity能够匹配我们的隐式Intent,如果不做判断就有可能出现错误。判断方法有两种:采用PackageManager的resolveActivity方法或者Intent的resolveActivity方法,如果它们找不到匹配的Activity就会返回null,我们通过判断返回值就可以规避上述错误了。另外,PackageManager还提供了queryIntentActivity方法,这个方法和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.DEFAULT"/>这个category的Activity。使用这个标记位的意义在于,只要上述两个方法不返回null,那么startActivity一定可以成功。如果不用这个标记位,就可以把intent-filter中category不含DEFAULT的那些Activity给匹配出来,从而导致startActivity可能失败。因为不含有DEFAULT这个category的Activity是无法接收隐式Intent的。
0 0
原创粉丝点击