Intent filters

    技术2022-05-20  61

    ==================================================

    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.


    最新回复(0)