原则上一个Intent不应该即是显式调用有是隐式调用,如果二者共存以显式调用为主。
显式调用
需要明确指定被启动对象的组件信息,包括包名和类名。一般是在相同的应用程序内部实现的。
Intent intent = new Intent(MainActivity.this, TestActivity.class);
startActivity(intent);
隐式调用
IntentFilter中设置过滤信息action、category、data,系统根据隐式意图中的设置匹配过滤信息,只有同时匹配action类别、category类别、data类别才是能成功启动目标Activity。另外一点,一个Activity可以设置多个intent-filter,匹配任意一组即可。一般是用于在不同应用程序之间。
action的匹配规则
- 一个intent-filter中可以有多个action
- 只要intent中的action能和intent-filter中的任何一个action相同则匹配成功。
- 需要注意的是,intent中没有指定action,那么匹配失败。
- 除此之外,action区分大小写。
category的匹配规则
Intent中没有category可以匹配,写了就必须是intent-filter中定义的
- category的匹配规则和action不同,intent中如果出现了category,不管有几个,都必须是intent-filter中已经定义的category,也就是说intent可以没有category,一旦有,每个都必须和intent filter中定义的任意一个category相同。
- 那为什么我们没在intent filter中加android.intent.category.DEFAULT这个category会报错呢?
原因是系统在调用startActivity或者startActivityForResult的时候会默认在intent中加上android.intent.category.DEFAULT这个category。
还是以两个Activity之间的跳转为例:
Intent intent = new Intent();
intent.setAction("com.dev.test");
intent.addCategory("com.dev.testcat");
startActivity(intent);
AndroidManifest.xml中
<activity android:name=".TestActivity">
<intent-filter>
<action android:name="com.dev.test"/>
<category android:name="com.dev.testcat"/>
//必须加上,否者报错
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
data的匹配规则
data的匹配规则和action类似,如果intent filter中定义了data,那么intent中也必须要定义可匹配的data,否者匹配失败。
data的结构
data由两部分组成,mimeType和URI。
- mimeType指媒体类型,比如image/jpeg、text/plaind、video/*等,可以表示图片、文本、视频等不同的媒体格式。
- URI的结构
URI结构解析
data的过滤规则(1)
data规则不完整。如下所示
<intent-filter>
<data android:mimeType="image/*"/>
</intent-filter>
intent.setDataAndType(Uri.parse("file://abc"),"image/*");
- 这种规则指定了媒体类型为所有类型的图片,那么intent中的mimeType属性必须为“image/*”才能匹配成功
- 这种情况虽然没有指定URI,但URI部分的schema默认值为content或file。也就是说虽然没有指定URI,但是intent中的URI部分的schema必须为content或者file才能匹配成功,这点尤其需要注意。
data的过滤规则(1)
定义了多组data规则,并且每个data都定义了完整属性,既有URI又有mimeType。如下所示
<intent-filter>
<data android:mimeType="video/mpeg" android:scheme="http" ... />
<data android:mimeType="audio/mpeg" android:scheme="http" ... />
...
</intent-filter>
- 为了匹配这种intent filter,我们也需要在intent中完整定义其中一组data规则才能匹配成功。
- 另外,如果要为intent指定完整的data,必须调用setDataAndType方法,不能先调用setData再调用setType,因为这两个方法彼此会清除对方的值。
作者:Dueeeke
链接:https://www.jianshu.com/p/3d077bfd5d29
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
网友评论