Activity的启动方式分为两种:
- 显式启动 通过指明启动的Activity类
- 隐式启动 通过Intent匹配目标组件的
IntentFilter
中设置的信息。如果不匹配,就无法启动目标Activity。
隐式启动中IntentFilter的作用
IntentFilter主要包括 : action
category
data
。只有Intent完全匹配三者,才能成功启动Activity。一个Activity可以拥有多个IntentFilter
,一个Intent只要能匹配其中一个,就能成功启动Activity。
1 | <activity android:name=".MyActivity"> |
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
1 | <intent-filter> |
Intent中的mimeType必须是image/*
才能匹配。这里的过滤规则虽然没有指定URI,但是scheme默认为contene
和file
。
只设置mimeType的intent.setType("image/*")
将不能匹配。
需要同时设置 :
1 | intent.setDataAndType(Uri.parse("file://xxx"), "image/*"); |
intent.setType和intent.setData不能分开调用,因为两者都会清空彼此的信息
从Android源码中可以看到 :
1 | public Intent setData(Uri data) { |
1 | public Intent setType(String type) { |
实例2
1 | <intent-filter> |
这个data规则
1 | intent.setDataAndType(Uri.parse("http://xxx"),"image/jpeg"); |
或者
1 | intent.setDataAndType(Uri.parse("http://zzz"),"video/mpeg"); |
都可以匹配。
data的属性可以同行写,也可以分开下。
1 | <data |
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 作为匹配的选项。一般使用
1 | if (intent.resolveActivity(getPackageManager()) == null) { |
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!