Activity的启动方式分为两种:
- 显式启动 通过指明启动的Activity类
- 隐式启动 通过Intent匹配目标组件的
IntentFilter
中设置的信息。如果不匹配,就无法启动目标Activity。
隐式启动中IntentFilter的作用
IntentFilter主要包括 : action
category
data
。只有Intent完全匹配三者,才能成功启动Activity。一个Activity可以拥有多个IntentFilter
,一个Intent只要能匹配其中一个,就能成功启动Activity。
|
|
action 匹配规则
actioin 根据name
属性值进行匹配。Intent
的 action 需要与 name 的值完全一样,才算匹配成功。一个 IntentFilter 可以有多个 action , Intent 的 action 只要和其中一个action匹配成功就可以。一个Intent如果没有指定action,那么匹配失败。
category 匹配规则
category根据name
属性值进行匹配。Intent
要么不携带 category 参数,直接默认匹配。要么携带的 category 每一个都必须在 IntentFilter 中的 category 能匹配到。
Intent 不携带category也能匹配成功是因为 : 调用startActivity
和startActivityForResult
时,系统会默认为Intent添加<category android:name="android.intent.category.DEFAULT" />
category。所以想要Activity能接受隐式调用,就必须给Activity指定<category android:name="android.intent.category.DEFAULT" />
这个category。
data 匹配规则
data的匹配和action类似,也是只要Intent的data能匹配多个data中的一个就匹配成功。
data 由两部分组成 :
- mineType 媒体类型。比如
image/*
video/*
。可以表示图片,文本,视频等不同媒体格式。 - URI
URI的结构
<scheme>://<host>:<port>/[<[path]>|[pathPrefix]|[pathPattern]]
- scheme : URI的模式,比如http file content等。如果Intent的URI中没有指定
scheme
,那么整个URI的其他参数无效,这个URI也就无效。过滤规则中的scheme默认需要匹配content
或file
。 - host : URI的主机名。比如
www.mm.com
。如果Intent的URI中没有指定host
,那么整个URI的其他参数无效,这个URI也就无效。 - port : URI的端口号。只有Intent的URI中指定了scheme和port参数时才有意义。
- path pathPattern pathPrefix : 表示路径信息
- path 完整路径。
- pathPattern 完成路径。可以包含通配符
*
,表示0个或多个任意字符 - pathProfix 路径的前缀信息。
实例1
<intent-filter>
......
<data android:mimeType="image/*" />
</intent-filter>
Intent中的mimeType必须是image/*
才能匹配。这里的过滤规则虽然没有指定URI,但是scheme默认为contene
和file
。
只设置mimeType的intent.setType("image/*")
将不能匹配。
需要同时设置 :
|
|
intent.setType和intent.setData不能分开调用,因为两者都会清空彼此的信息
从Android源码中可以看到 :
|
|
|
|
实例2
|
|
这个data规则
intent.setDataAndType(Uri.parse("http://xxx"),"image/jpeg");
或者
intent.setDataAndType(Uri.parse("http://zzz"),"video/mpeg");
都可以匹配。
data的属性可以同行写,也可以分开下。
<data
android:host="www.xxx.com"
android:mimeType="image/*"
android:scheme="http" />
-------------------------------------
<data android:host="www.xxx.com" />
<data android:scheme="http" />
<data android:mimeType="image/*" />
Android的其他组件,Service BroadcastReceiver的IntentFiler匹配规则和Activity的类似。
- 当隐式启动一个Activity时,可以使用Intent的
resolveActivity(PackageManager pm)
方法判断是否有匹配的activity。 - 也可以调用PackageManager的
resolveActivity(Intent itent,int flag)
方法判断。- 第二个参数 flag 作为匹配的选项。一般使用
MATCH_DEFAULT_ONLY
参数。 - MATCH_DEFAULT_ONLY 只匹配 intent-filter 中声明了
<category android:name="android.intent.category.DEFAULT" />
的Activity。因为没有声明这个category的Activity不能隐式调用。
- 第二个参数 flag 作为匹配的选项。一般使用
if (intent.resolveActivity(getPackageManager()) == null) {
//证明没有对应的activity
}