当一个组件用过Intent表示了启动或触发另一个组建的“意图”之后,这个意图可以分为两类:
1·显示Intent:明确指定需要启动或者触发的组件的类名
2·隐式Intent:只是指定需要启动或者触发的组件应满足怎样的条件
对于显示Intent而言,系统无需对该Intent做任何解析,系统直接找到指定的目标组件,启动或触发它即可。
对于隐式Intent而言,android系统要对该Intent进行解析,解析出他的条件,然后再去系统中国查找与之相匹配的目标组件。找到符合条件的组件,就启动或者触发他们。
那么android系统如何判断被调用组件是否符合隐式Intent呢?这就需要靠IntentFilter来实现,被调用组件可通过声明IntentFilter来声明自己所满足的条件----也就是声明自己到底能处理哪些隐式Intent。
IntentFilter描述了一个组件愿意接收什么样的Intent对象,android将其抽象为android.content.IntentFilter类。在android的androidManifest.xml配置文件中可通过<intent-filter>节点为一个activity指定其IntentFilter,以便告诉系统改activity可以相应什么类型的Intent。
每个component都会定义一个或多个IntentFilter,用于表明其可处理的intent.
定义的方法: 在<activity>, <receiver>, <service>元素中增加一个或多个<intent-filter>子元素. 如:
<!-- 声明作为程序入口的Activity -->
<activity android:name=".FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />决定应用程序最先启动的Activity
<category android:name="android.intent.category.LAUNCHER" />决定应用程序是否显示在程序列表里
</intent-filter>
</activity>
当我们使用startActivity(intent)来启动另外一个activity时,如果直接指定intent对象的component属性,那么Activity Manager将试图启动其Component属性指定的activity。否则android将通过Intent的其他属性从安装在系统中的所有activity中查找与之最匹配的一个启动,如果没有找到合适的activity,应用程序会得到一个系统抛出的异常。这个匹配过程如下:
Activity中 Intent Filter 的匹配过程
android系统处理隐式Intent时, 会比较Intent和IntentFilter的action, data, category属性, 如果以上3个属性全都相符的话, 则IntentFilter所属的component就可以作为目标组件的候选(存在多个符合条件的component时).
Action 匹配
Action 是一个由用户定义的字符串,用于描述一个 Android 应用程序组件,一个intent最多只能定义一个action,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的 activity 定义时可以在其 <intent-filter > 节点指定一个 action 列表用于标示 activity 所能接受的“动作”,例如:
<intent-filter > <action android:name="android.intent.action.MAIN" /> <action android:name="com.zy.myaction" /> …… </intent-filter> |
如果我们在启动一个 Activity 时使用这样的 Intent 对象:
Intent intent =new Intent(); intent.setAction("com.zy.myaction"); |
那么所有的 Action 列表中包含了“com.zy.myaction ”的 Activity 都将会匹配成功。
通过action测试的条件为: filter定义了intent的action. 例如intent的action为"android.intent.action.MAIN", 则定义了"android.intent.action.MAIN"这个action的filter都能通过action测试(当然, filter还可以包含更多额外的action).如果filter没有定义action, 则这个filter将阻塞所有intent. 如果intent没有定义action, 那么只要filter定义了action就可以通过action测试.
Android 预定义了一系列的 Action 分别表示特定的系统动作。这些 Action 通过常量的方式定义在 android.content. Intent中,以“ACTION_ ”开头。我们可以在 Android 提供的文档中找到它们的详细说明。
URI 数据匹配
一个 Intent 可以通过 URI 携带外部数据给目标组件。在 <intent-filter > 节点中,通过 <data/> 节点匹配外部数据。
mimeType 属性指定携带外部数据的数据类型,scheme 指定协议,host、port、path 指定数据的位置、端口、和路径。如下:
<data android:mimeType="mimeType" android:scheme="scheme" android:host="host" android:port="port" android:path="path"/> |
如果在 Intent Filter 中指定了这些属性,那么只有所有的属性都匹配成功时 URI 数据匹配才会成功。
Category 类别匹配
<intent-filter > 节点中可以为组件定义一个 Category 类别列表,当 Intent 中包含这个列表的所有项目时 Category 类别匹配才会成功。