Android InterFilter 匹配

前言

一般来说,启动Activity的方法有两种,显式启动和隐式启动。对于显示启动来说,只需要实例化一个Intent对象,指明被启动对象的组件信息,包括包名以及类名。例如

1
Intent intent=new Intent(MainActivity.this,OtherActivity.class);

原则上是单独的使用隐式启动和显式启动,如果两者并存的话,以显式启动为准。
隐式调用需要Intent能够匹配目标组件的IntentFilter设置的过滤信息,如果不匹配的话是不能正常的启动Activity。Intent中需要过滤的信息包括:action、category和data。

IntentFilter的匹配规则

一个过滤列表中的action,category,data可以有多个,所有的action,category,data分别构成不同的类别。只要有一个Intent能够同时匹配action、category、data类别才能匹配成功。一个Activity可以有多个IntentFilter,只要成功的符合一组IntentFilter就可以启动相应的Activity。

action的匹配规则

action是一个字符串,系统定义了一些,同时也支持自定义此字符串。action严格区分大小写

一个过滤规则中可以有多个action,只要有一个action和intent匹配,就可以匹配成功。

IntentFilter必须存在,否则不能启动Activity。

category匹配规则

category也是字符串,系统也有默认的字符串,和action匹配规则不同的是,在intent中可以不用特别指明category属性。

IntentFilter中必须要有<category android:name="android.intent.category.DEFAULT"/> 无论intent是否调用addCategory()方法。

在Manifest文件中也可以像action一样设置多个category标签,只要有一个匹配就可以。

1
2
3
4
5
6
7
Intent intent = new Intent();
intent.setAction("com.example.dimple.action.activity2");
intent.addCategory("com.example.dimple.category.activity2");
//判断是否有Activity能够匹配intent。防止启动报错!
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

data的匹配规则

data的匹配规则和action类似,如果过滤规则中定义了data,那么在Intent中也需要有可以与之匹配的data。但data可以省略不写。

语法如下:

1
2
3
4
5
6
7
<data android:scheme="string" 
android:host="string"
android:port="number"
android:path="/string"
android:pathPattern="string"
android:pathPrefix="/string"
android:mimeType="string"/>

data 由两部分组成,mimeType和URL(mimeType表示媒体类型,比如image/jpg、audio/mp3等,可以表示图,文本等不同格式),URL的格式如下:

<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]

  • scheme:URL的模式,比如http、file、content,如果URL中没有scheme,那么URL无效。
  • host:主机名称,比如www.bianxiaofeng.com,如果没有host,则URL无效。
  • port:端口
    -path、pathPattern、pathPrefix:表示路径信息

总结

在通过隐式启动Activity的时候,最好是通过PackageManager的resolveActivity方法或者Intent的resolveActivity方法来判断下是不是有能够负责匹配规则的Activity存在,防止异常出错。

-------------本文结束感谢您的阅读-------------
na,给我一个棒棒糖!