3.1.0 Intent filter基本概念

前面章节我们说到了Intent,Intent对象中除了ComponentName可以直接指定目标组件外,其它的属性都无法直接指定目标组件。当然我们这里不指使用Activity的内部方法如startActivity或者intent的setClass方法可以指定目标组件。单独的属性是无法确定目标组件的。那Android怎么办呢?Android如何根据一个intent对象找到目标组件呢?Intent在系统中,从概念上分为显示intent和隐式intent。其中显示intent,就是前面所说的通过指定intent的目标组件名称来实现,这种intent需要知道目标组件名称。另一种所谓隐式intent,这种intent用intent filter进行处理。Android对每个组件设置intent filter来订阅intent 消息属性。这个有点类似于Linux IPC消息,发送者将消息发到Kernel,然后由组件通过intent filter从Kernel上取得消息。

显示intent和隐式intent在具体应用中,通常是针对不同的场景来进行应用,如显示intent通常是在一个应用的内部组件之间,这样可以知道具体目标组件的类名。而隐式intent就不一定了,通常可以打开如电话、短信等基础Android应用。前面我们说intent filter是针对隐式intent,为了组件能够匹配到具体合适的intent。Android内部的intent解析机制是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其定义的Intent,最终找到匹配的intent。在这个解析过程中,Android通过intent的Action、Category和Data这三个属性来进行判断,并且是都满足的情况才可启动这个组件。如果一个filter的Action可以,但是category不对,也不行的。

3.1 Android组件intent filter_Android

如上图所示,对intent filter来说,进行ACTION, DATA,CATEGORY的分析比较是一个intent filter的基本机制。下面分述如下:

【1】Action

如果一个组件想要接收某个intent,那么它的intent filter中action元素必有与这个intent相同的action(在定义action的前提下)。Intentfilter中定义的action,不再像前面使用缩写的常量,需要使用android.intent.action.EDIT之类。创建一个Intent filter非常简单,只需要在Activity 的子元素中定义,如下图所示:

3.1 Android组件intent filter_休闲_02

接着定义Activity和Intent.将intent的Action设为其中一个Action.

3.1 Android组件intent filter_Android_03

【2】Category

同前面Action一样,一个组件想要响应一个intent就必须与这个intent具有相同的Category,但是通常有些intent对DEFAULT Category 都不设置,默认就是这个Category,但是对Intent filter那是不可以的,一定要有DEFAULT Category设置。如前面所述,Android 2.2以后,对intent filter要求更加严格,也就是说,前面的Action一定要存在。否则无法查找到相应的组件。如下所示定义一个Intent的一个自定义ACTION和一个CATEGORY。

3.1 Android组件intent filter_Android_04

接着再定义一个intent filter用来匹配对应用的intent.

3.1 Android组件intent filter_Android_05

 

【3】Data

Data属性是Android要访问的数据,和前面两个属性一样,在intent filter中也可以声明Data属性。声明Data属性需要同时指定访问数据的URI和MIME类型。在Intent filter中Data 属性分为四个独立的属性进行设置,共同组成一个URI:scheme://host:port/path

3.1 Android组件intent filter_职场_06

从这里可以看出intent filter在匹配data时候的一些规则的不同,它是以intent filter为最大集,比喻说intent filter定义了http://www.sina.com.cn,但实际上它是可以匹配http://www.sina.com.cn/boke等子路径的。同样对MIME类型,更是如此,它可以支持通配符如"text/*”或者“audio/*”等。Data属性匹配规则如下:

【1】如果intent 对象中没有包含data,<intent-filter>列表中也没有包含DATA,这种情况下一般通过ACTION来匹配。

【2】如果Intent 对象包含URI但是没包括类型,并且类型不能从URI中自动识别,那么<intent-filter>列表中也只能包含URI,才能匹配

【3】相反,如果Intent对象只包含类型,不包含URI,那么<intent-filter>也只能含类型,不含 URI

【4】如果Intent 对象中既包含URI又包括Type,那么在<intent-filter>中也必须二者都包含。

创建一个Intent时设置data 属性,如下所示,使用Uri类进行parse.

3.1 Android组件intent filter_移动开发_07

在<intent-filter>中使用data属性进行匹配。

3.1 Android组件intent filter_Android_08

3.1.1 Intent filter 类及packageManager

前面我们着重谈到的都是通过在xml文件中定义intent filter,实际上intent filter也是一个类,如下图所示。它可以在receiver中直接注册使用。

3.1 Android组件intent filter_职场_09

从类中,你可以使用add方法将相关属性填入其中。