==================================================
Intent的分类
==================================================
Intent大体上可以分成两类
*. 显式Intent,它通过组件名来指定要运行的目标组件(通过它的setComponent()方法),
因为指定了组件名,所以它要运行的组件是确定的;其它程序开发者并不知道某个程序
组件的名字,所以显式Intent通常用于程序内的组件调用,比如启动同一程序的其他
服务或Activity。
*. 隐式Intent, 它不通过组件名来启动目标组件, 系统必须通过其他的手段找到合适的
目标组件, 隐式Intent一般用于启动其他程序的组件.
===================================================
Intent filters
===================================================
如上所说, 对于隐式Intent不指定目标组件名, Android必须用其他方法来找到目标组件,
这需要Intent和组件提供必要的信息.
对于组件来说, 它可以包含多个Intent filter, 这些Intent filter告知系统它可以处理
哪些Intent. 隐式Intent必须通过组件的Intent fitler测试才能启动该组件.
组件可以在AndroidManifest.xml指定它的Intent filter, 它包含action, data, category
三种Filter, 与Intent的这三种属性对应, 如:
<activity . . .>
<intent-filter . . . >
<action android:name="com.example.project.SHOW_CURRENT" />
<action android:name="com.example.project.SHOW_RECENT" />
<action android:name="com.example.project.SHOW_PENDING" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="video/mpeg" android:scheme="http" . . . />
<data android:mimeType="audio/mpeg" android:scheme="http" . . . />
. . .
</intent-filter>
</activity>
一个Intent必须通过三种Filter的测试才能调用该组件, 但上面可以看到每种Filter可以
有多项, 对于每种Filter, 只要通过其中一项就算通过了.
下面分别描述:
*. Action测试
<intent-filter . . . >
<action android:name="com.example.project.SHOW_CURRENT" />
<action android:name="com.example.project.SHOW_RECENT" />
<action android:name="com.example.project.SHOW_PENDING" />
. . .
</intent-filter>
一个Intent的Action必须匹配Filter的Action列表中的一项, 才能通过, 如果Intent或
组件的Filter没有指定Action, 会导致下两个结果:
*. 如果组件的Intent Filter没有指定任何Action, 那么所有Intent都将不通过测试.
*. 但另一方面, 如果Intent没有指定Action, 则它将通过测试, 即使组件的Intent
Filter没有指定任何Action.
*. Category测试
<intent-filter . . . >
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
. . .
</intent-filter>
一个Intent如果要通过测试, 则它包含的所有category都必须通过Filter的category列表
中的一项. 因此, 如果一个Intent没有category, 它就总是可以通过测试. 但有一个
例外的情况: 对于传递给Activity(调用startActivity())的隐式Intent, 系统默认它
带有一个 android.intent.category.DEFAULT 的category, 所以Activity的Intent Filter
必须包含一项 android.intent.category.DEFAULT, 才能使这个Intent通过测试.
不过如果Activity的Intent Filter带有 android.intent.action.MAIN 和
android.intent.category.LAUNCHER , 就不再需要包含android.intent.category.DEFAULT 了.
*. Data测试
<intent-filter . . . >
<data android:mimeType="video/mpeg" android:scheme="http" . . . />
<data android:mimeType="audio/mpeg" android:scheme="http" . . . />
. . .
</intent-filter>
Data测试主要是测URI和数据类型(mimeType), URI的形式大概如下:
scheme://host:port/path
比如:
http://www.douban.com:8080/people
data filter将URI分成多个属性, 如下:
<data android:host="string"
android:mimeType="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:port="string"
android:scheme="string" />
系统只比较出现的URI属性, 比如Data Filter只指定android:scheme, 那么所有包含
这个scheme的URI都可以匹配这个Filter.
Data的测试规则如下:
*. 如果一个Intent没有包含URI和数据类型, 那么只当Data Filter也没有包含任何URI
和数据类型时才能通过.
*. 如果一个Intent包含URI但没有包含数据类型(并且数据类型不能从URI推断出来),
那么只当Intent的URI与Filter的URI匹配, 并且Filter也没有数据类型时才能通过.
*. 如果一个Intent包含数据类型但没有包含URI, 那么只当Filter包含同样的数据
amp;nbsp; 类型并且没有包含URI时才能通过.
*. 如果一个Intent即包含URI也包含数据类型(或可以从URI推断出数据类型), 那么
当它匹配Filter的数据类型时通过数据类型部分的测试, 当它匹配Filter的URI时
通过URI部分的测试;
如果Intent的URI是content: 或 file: , 并且Filter没有指定URI时通过URI测试,
换名话说, 一个Filter只列出数据类型, 则假定支持content: 或 file: 类型的URI.