我们都知道,intent分成两种:显式和隐式,显式需要制调用activity的包名和类名,而隐式是通过过滤规则来确定的。
在manifest.xml文件里我们可以给需要的Activity加上过滤的匹配规则,主要有这几个方面
<intent-filter>
<action android:name=".."/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:mimeType="string"
/>
intent-filter>
1.首先分析intent-filter 的匹配原则:
一个activity只要它下面的一个intent-filter匹配成功就代表该activity匹配成功
2.分析intent-filter中action 的匹配
在intent里面我们可以通过intent.setAction(“”)的方式设置一个仅且最多一个action,在上面介绍的样例代码中我们可以看到一个intent-filter中可以有多个action,只需要intent-filter中的一个action和intent中指定的action相匹配则匹配成功。
3.category的匹配
intent-filter中也可以有多个category,而intent中也可以用intent.addCategory()的方式指定多个category,那么category匹配成功的条件是:intent中所指定的category条目,intent-filter中必须都有(也可以多)才算匹配成功比如,如果intent中指定了category有三条(“1”,“2”,“3”),那么在activity的intent-filter里面必须包含, ,…等等
要特别注意的是:我们在调用startActivity()或者startActivityForResult()启动时,会默认加上一条category属性,即android.intent.category.DEFAULT.所以一个activity如果想要被隐式调用就必须在intent-filter中加上这条category,不然就匹配不上。
data的匹配
data由两部分组成:URI和mimeType,mimeType指媒体类型,比如:image/png,URI的结构如下:
://:/[path]
scheme:URI的模式,data中scheme未指定则其他项都无效,URI无效
host:主机名,host未指定则其他项都无效,URI无效
port:端口,只有当scheme和host都指定才有效
path:路径
data的匹配规则大致可以这么理解:intent-filter中data包括的项,intent中也必须全部都有才算匹配成功
举几个例子:
例子一:
<intent-filter>
<action android:name="abc"/>
<data android:mimeType="image/png"/>
</intent-filter>
//在启动时
Intent intent=new Intent();
intent.setAction("abc");
intent.setType("image/png");//intent-filter只有mimeType所以只需要指定mimeType就好
例子二:
<intent-filter>
<action android:name="abc"/>
<data android:mimeType="image/png" android:scheme="http" android:host="www.xx.com" />
</intent-filter>
//在启动时
Intent intent=new Intent();
intent.setAction("abc");
intent.setType("image/png");//intent-filter有mimeType要指定mimeType
intent.setData(Uri.parse("http://www.xx.com"));//这样写逻辑上能匹配,但是是错误的,原因解释如下:
intent.setDataAndType(Uri.parse("http://www.xx.com"),"image/png);//这样写才是对的
/*
intent.setData()和intent.setType()会相互清除对方
public Intent setData(Uri data){
mData=data;
mType=null;
return this;
}
public Intent setType(String type){
mType=type;
mData=null;
return this;
}
*/
注意在intent-filter中如果没有写出data 的scheme那么他是默认值的,默认值为content或者file
比如:
"abc"/>
"image/png" />
//不能匹配的设置方法
intent.setDataAndType(Uri.parse("http://"),"image/png");
//成功匹配的设置方法
intent.setDataAndType(Uri.parse("content://"),"image/png");
//或者
intent.setDataAndType(Uri.parse("file://"),"image/png");
总的规则可以概括为:
action中选一个(intent中的action,intent-filter中有一个满足就好了)
category 和data是你有我有大家有(intent指定的category,intent-filter中必须全有才能成功匹配,intent-filter中为data设置的项,intent中必须都有并一致)
category还必须有android.intent.category.DEFAULT(intent-filter中必须有,因为startActivity时会默认为intent 加上DEAULT)