Intent过滤器

本文介绍了Android系统中Intent过滤器的工作原理,它是如何通过匹配Intent的动作、类别和数据来找到合适的Activity、Service或BroadcastReceiver。Intent过滤器可以在AndroidManifest.xml中定义,包括<action>、<category>和<data>标签来指定组件支持的动作、类型和数据格式。匹配规则涉及动作、类别的匹配,以及Uri数据部分的匹配,并考虑了优先级。IntentResolutionDemo示例展示了如何注册和配置Intent过滤器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

隐式启动Activity时,并没有在Intent中指明Acitivity所在的类,因此,Android系统一定存在某种匹配机制,使Android系统能够根据Intent中的数据信息,找到需要启动的Activity。这种匹配机制是依靠Android系统中的Intent过滤器(Intent Filter)来实现的。
Intent过滤器是一种根据Intent中的动作(action)、类别(category)和数据(data)等内容。对适合接收该 Intent 的组件进行匹配和筛选的机制。Intent过滤器可以匹配数据类型、路径和协议,还可以确定多个匹配项顺序的优先级(priority)。应用程序的Activity、Service和 BroadcastReceiver 组件都可以注册Intent过滤器。这样,这些组件在特定的数据格式上则可以产生相应的动作。
为了使组件能够注册Intent过滤器,通常在AndroidManifest.xml 文件的各个组件下定义 < intent-filter >节点,然后再< intent-filter >节点中声明该组件所支持的动作、执行的环境和数据格式等信息。当然,也可以在程序代码中动态的为组件设置Intent过滤器。< intent-filter >节点支持< action >标签 、 < category >标签 和 < data >标签,分别用来定义Intent过滤器的动作、类型和数据。 < intent-filter >节点支持的标签和属性说明如下图:
< intent-filter > 节点属性

标签属性说明
actionandroid: name指定组件所能响应的动作
categoryandroid: category指定以何种方式去服务Intent请求的动作
dataAndroid: host
android: mimetype
android: path
android: port
android: scheme
指定一个有效的主机名
指定组件能处理的数据类型
有效的URI路径名
主键的有效端口号
所需要的特定协议

< category >标签用来指定Intent过滤器的服务方式,每个Intent过滤器可以定义多个< category >标签,我们可以使用自定义的类别,或者使用系统提供的类别。Android系统提供的类别可以参考下表:

说明
ALTERNATIVEIntent数据默认动作的一个可替换的执行方法
SELECTED_ALTERNATIVE和ALTERNATIVE类似,但替换的执行方法不是指定的,而是被解析出来的
BROWSABLE声明Activity可以由浏览器启动
DEFAULT为Intent过滤器中定义的数据提供默认动作
HOME设备启动后显示的第一个Activity
LAUNCHER在应用程序启动时首先被显示

这种Intent 到 Intent 过滤器的映射过程称为“Intent解析”。Intent解析可以在所有的组件中,找到一个可以与请求的Intent达成最佳匹配的Intent过滤器。Android系统中Intent解析的匹配规则为:

  1. Android系统把所有应用程序包中的 Intent 过滤器集合在一起,形成一个完整的Intent过滤器列表。
  2. 在Intent与Intent过滤器进行匹配时,Android系统会将列表中所有Intent过滤器的“动作”和“类别”与Intent进行匹配,任何不匹配的Intent过滤器都将被过滤掉。没有指定“动作”的Intent过滤器可以匹配任何的Intent,但是没有指定“类别”的Intent过滤器只能匹配没有“类别”的Intent。
  3. 把Intent数据Uri的每个子部与Intent过滤器的< data >标签中的属性进行匹配,如果< data >标签指定了协议、主机名、路径名或MIME类型,那么这些属性都要与Intent的Uri数据部分进行匹配,任何不匹配的Intent过滤器均被过滤掉。
  4. 如果Intent过滤器的匹配结果多于一个,则可以根据在< intent-filter >标签中定义的优先级标签来对Intent过滤器进行排序,优先级最高的Intent过滤器将被选择。

    IntentResolutionDemo示例说明了如何在AndroidManifest.xml文件中注册Intent过滤器,以及如何设置< intent - filter >节点属性来捕获指定的Intent。
    AndroidManifest.xml的完整代码示例如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.satellitemenu">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".MyActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.LAUNCHER" />
            <data android:scheme="schemodemo" android:host="edu.hrbeu"/>
            </intent-filter>
        </activity>

    </application>
</manifest>

第一个Activity 的 Intent 过滤器:

动作是android.intent.action.MAIN,类别是android.intent.category.LAUNCHER ,由此可知,这个Activity是应用程序启动后显示的默认用户界面。

第二个Activity的Intent过滤器

动作是android.intent.action.VIEW,表示根据Uri协议,以浏览的方式启动相应的Activity;类别是android.intent.category.DEFAULT ,表示数据的默认动作;数据的协议部分是:android:scheme="schemodemo",数据的主机名称部分是 android:host="edu.hrbeu"。

在MainActivity.java文件中,定义了一个Intent用来启动另一个Activity,这个Intent与Activity设置的过滤器是完全匹配的。相关代码如下:

Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("schemodemo://edu.hrbeu/path"));
startActicity(intent);

代码中首先定义Intent,动作为Intent.ACTION_VIEW,与Intent过滤器的动作android.intent.action.VIEW匹配;Uri是shemodemo://edu.hrbeu/path,其中的协议部分为schemodemo,主机名为edu.hrbeu,也与Intent过滤器定义的数据要求完全匹配。因此代码中定义的Intent,在Android系统与Intent过滤器列表进行匹配时,会与AndroidManifest.xml文件中MyActivity定义的Intent过滤器完全匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值