隐式Intent和<intent-filter>的匹配规则

Intent可以划分成显式意图和隐式意图。

  • 显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了Intent应该传递给哪个组件。这时候IntentFilter的对这种Intent没有约束力。
  • 隐式意图:没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。这种情况下通过intent中的action,category,data,tpye 和Activity、Service、Broadcast Receiver中的IntentFilter进行匹配。若有多个目标组件同时可以匹配,则系统会提示用户进行选择。

隐式Intent和<intent-filter>的匹配规则

  1.  <intent-filter> 只包含action 和 category 只需要intent中的action 和 category 小于或等于<Intent-filter>范围,即可匹配成功(但是Intent必须指定action,否则系统报错)。
           例如:在AndroidManifest.xml 的定义如下
        <activity
            android:name=".ui.AboutUsActivity">
            <intent-filter>
                <action android:name="testAction1" />
                <action android:name="testAction2" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="category1" />
                <category android:name="category2" />
            </intent-filter>
        </activity>

      注意: Activity 如果想被隐式Intent 启动则<intent-filter>必须包含 <category android:name="android.intent.category.DEFAULT" />,因为startActivity(intent) 时候,默认给intent添加了android.intent.category.DEFAULT 的category 属性值。Service和BroadcastReceiver不必要。

     下面是几个Intent

                intent1.setAction("testAction1");

                Intent intent2 = new Intent();
                intent2.setAction("testAction2");

                Intent intent3 = new Intent();
                intent3.setAction("testAction2");
                intent3.addCategory("category1");

                Intent intent4 = new Intent();
                intent4.setAction("testAction1");
                intent4.addCategory("category1");
                intent4.addCategory("category2");

                Intent intent5= new Intent();
                intent5.setAction("testAction1");
                intent5.addCategory("category1");
                intent5.addCategory("category2");
                intent5.addCategory("category3");

                Intent intent6= new Intent();
                intent6.addCategory("category1");
  上面intent1, intent2, intent3, intent4都可以正常启动activity。intent5因为范围超过了intent filter不能启动activity,intent6因为没有设置action不能启动activity。

2. <intent-filter> 除了action和categroy外还包含 type,则要求intent中的type和Intent-Filter中的type 完全一直才能匹配( Data 和 type 都是在<data></data>标签中定义的)。
 例如:在AndroidManifest.xml 的定义如下
 
   <activity android:name=".ui.AboutUsActivity">
            <intent-filter>
                <action android:name="testAction1" />
                <data android:mimeType="abc/xyz" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
  下面是几个Intent:
                Intent intent1 = new Intent();
                intent1.setAction("testAction1");
                intent1.setType("abc/xyz");

                Intent intent2 = new Intent();
                intent2.setAction("testAction1");

                Intent intent3 = new Intent();
                intent3.setAction("testAction1");
                intent3.setType("xxx/yyy");

 intent1可以正常启动,intent2因为没有设置type不能正常启动,intent3因为设置的type和intent filter 中的type 不一致不能启动activity。

3. <intent-filter> 除了action和categroy外还包含 Data,则要求intent中的scheme,host,prot,path和Intent-Filter存在的对应属性一致就可匹配。(Intent-Filter中定义的Data可以少于Intent中的Data属性)
  也就是Intent中的Data属性一定要包含Intent-Filter中的所有Data属性并且属性值要相等。Intent-Filter定义了Data,则要求Intent必须要包含Data,否则匹配失败。
 例如:在AndroidManifest.xml 的定义如下
 
    <activity android:name=".ui.AboutUsActivity">
            <intent-filter>
                <action android:name="testAction1" />
                <action android:name="testAction2" />

                <data
                    android:host="www.csdn.com"
                    android:mimeType="abc/xyz"
                    android:scheme="lee" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="category1" />
                <category android:name="category2" />
            </intent-filter>
        </activity>
    下面是几个Intent:
 <span style="white-space:pre">	</span>Intent intent1 = new Intent();
        intent1.setAction("testAction1");
        intent1.setDataAndType(new Uri.Builder()
                .scheme("lee")
                .authority("www.csdn.com").build(), "abc/xyz");

        Intent intent2 = new Intent();
        intent2.setAction("testAction1");
        intent2.setDataAndType(new Uri.Builder()
                .scheme("lee")
                .authority("www.csdn.com")
                .path("/path").build(), "abc/xyz");

        Intent intent3 = new Intent();
        intent3.setAction("testAction1");
        intent3.setDataAndType(new Uri.Builder()
                .scheme("xxx")
                .authority("www.csdn.com").build(), "abc/xyz");

        Intent intent4 = new Intent();
        intent4.setAction("testAction1");
        intent4.setDataAndType(new Uri.Builder()
                .scheme("lee").build(), "abc/xyz");


  intent1和intent-Filter 完全匹配  可以正常启动activity 
intent2 中的Data属性比intent-filtet 属性多,可以正常启动activity
intent3 中的的Data属性值和intent-filter 的属性值不相等 不能启动activity
intent4 中的属性比intent-filter的属性值少  不能启动activity

1.如果Intent Filter中同时定义了data和Type,需要调用setDataAndType方法,不能调用setData 和 setType,两个方法相互覆盖
2.如果Intent Filter中要设置path,path的值的前面要加上"/"(在实际使用发发现没有"/",无法正常触发)。例如设置android:path="/main" 则intent.setData(new Uri.Builder().path("main").build) 和设置intent.setData(new Uri.Builder().path("/main").build()) 都可以。
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值