概述
前言
本人对Activity的两种启动,尤其是隐式启动有了新的理解,特此记录
1.Activity两种启动方式
①显式启动:需要明确地指定被启动对象的组件信息,包括包名和类名
(一般用在一个应用程序内部)
例如
Intent intent = new Intent();
intent.setClass(SecondActivity.this,ThirdActivity.class);
startActivity(intent);
②隐式启动:需要Intent能够匹配目标组件的intent-filter中所设置的过滤信息。主要是有三个:action、category、data,并且这三个同时匹配,才能够启动
(一般用在不同应用程序之间)
例如
Intent intent = new Intent("com.ryg.charpter_1.c");
intent.addCategory("com.ryg.category.c");
intent.setDataAndType(Uri.parse("content://abc"),"text/plain");
startActivity(intent);
对应的Activity可以是
<activity
android:name="com.ryg.chapter_1.ThirdActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:taskAffinity="com.ryg.task1" >
<intent-filter>
<action android:name="com.ryg.charpter_1.c" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
值得一提的是,一个Activity中可以有多个intent-filter,一个Intent只要能匹配其中任何一组intent-filter即可启动对应的Activity
2.action、category、data的匹配规则
(1)action的匹配规则
①要求字符串完全相同
②要求Intent中必须有action,且必须和intent-filter中的其中一个action相匹配(规则就是字符串完全相同)
(2)category的匹配规则
①category可以不设置
②如果设置,则和action的匹配规则一样
- 问题:category不设置,怎么玩?
其实如果要让我们的activity能够接收隐式调用,就必须在intent-filter中指定"android.intent.category.DEFAULT"
这个category。然后如果没有在Intent中设置category,则当我们调用startActivity
或者startActivityForResult
的时候会默认为Intent加上"android.intent.category.DEFAULT"
,所以可以匹配成功,没毛病。
(3)data的匹配规则
和action基本一样,区别是,如果intent-filter中没有指定data,那么Intent里面可以不设置。而action是必须要在intent-filter中最少指定一个
- data由两部分组成,mimeType(媒体类型)和URI
①mimeType(媒体类型)
一般包括image/jpeg
,audio/mpeg4-generic
和video/*
等
②URI
URI的结构为
<scheme>//<host>:<port>/[<path> | <pathPrefix>|<pathPattern>]
scheme:URI的模式,比如http、file、content等,如果URI中没有指定scheme,那么整个URI的其他参数无效。
host:URI的主机名,比如www.baidu.com,如果host没有指定那么整个URI的其他参数无效。
port:URI的端口号。
path,pathPattern,pathPrefix:这三个参数指定路径信息
URI的例子:
content://com.example.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info
3.使用的正确姿势
一般使用隐式方式启动一个Activity的时候,要做一个判断,来看是否有匹配Intent的Activity。那么这个判断的方法有三种,分别是
PackageManager的resolveActivity
方法
Intent的resolveActivity
方法
PackageManager的queryIntentActivities
方法
前两种可以理解为一种,也就是说总共是两个具体的方法,分别是resolveActivity
和queryIntentActivities
。
两者的区别是:resolveActivity
返回最佳匹配的Activity信息,queryIntentActivities
返回所有成功匹配的Activity信息。
使用实例如下
if (getPackageManager().resolveActivity(intent, 0) == null) {
// 说明系统中不存在这个activity
}
if(intent.resolveActivity(getPackageManager()) == null) {
// 说明系统中不存在这个activity
}
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, 0);
if (list.size() == 0) {
// 说明系统中不存在这个activity
}
其中,最后面这个0是个flags
,内部其实是MATCH_DEFAULT_ONLY
这个标记位,它的含义是仅仅匹配那些在intent-filter中声明了"android.intent.category.DEFAULT"
的这个category的Activity。从而使得匹配出来的Activity全都是支持隐式调用的,避免出现虽然匹配但是不支持隐式调用的这种问题。
4.经典的组合
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER">
这一对表明这是一个程序的入口Activity。
最后
以上就是失眠吐司为你收集整理的IntentFilter的匹配规则随想录的全部内容,希望文章能够帮你解决IntentFilter的匹配规则随想录所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复