Intent详解(二)----Intent过滤器

本文详细介绍了Android系统中Intent过滤器的使用方法,包括其组成部分如action、category和data的属性及用途,同时还深入探讨了几种常见Category的作用及其应用场景。

上次博客中,介绍了Intent的启动Actiity的过程,这次来开始研究Intent过滤器。

开始Intent过滤器之前,首先可以看下过滤器的三个标签,具体参看下表。

标签

属性

说明

<action>

android:name

指定组件所能响应的动作,用字符串表示,通常由Java类名和包的完全限定名构成

<category>

android:name

指定以何种方式去服务Intent请求的动作

 

 

<data>

android:host

指定一个有效的主机名

android:mimetype

指定组件能处理的数据类型

android:path

有效的URI路径名

android:port

主机的有效端口号

android:scheme

所需要的特定协议

Category可以由系统提供也可以自定义,这里附上一张系统提供的Category标签表:

说明

ALTERNATIVE

Intent数据默认动作的一个可替换的执行方法

SELECTED_ALTERNATIVE

和ALTERNATIVE类似,但替换的执行方法不是指定的,而是被解析出来的

BROWSABLE

声明Activity可以由浏览器启动

DEFAULT

为Intent过滤器中定义的数据提供默认动作

HOME

设备启动后显示的第一个Activity

LAUNCHER

决定程序是否显示下程序列表中(一般为桌面)

接下来将分别介绍几个常用Category的用途,首先是HOME,HOME的第一个作用是设备开机时会给我们提供选择进入哪个页面,系统会列出所有的可供选择的Activity;HOME的另一个作用是在应用中当我们点击home键之后,同样的会弹出一个选择页面,结果如下图两张图,左边是开机时的,右边是点击home键图。

              

DEFAULT:如果一个Activity需要隐式启动,那么必须给它加上一个DEFAULT标签,但是不仅仅只限于一个DEFAULT,还可以添加其他的Category。


LAUNCHER和MAIN:

android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里。android.intent.action.MAIN决定应用程序中最先启动的Activity。

 

下面我们来测试几种情形:

第一种,有MAIN无LAUNCHER:

结果:直接运行app提示无默认Activity,运行单独的Activity可以运行,但是着桌面没有图标。


第二种,有LAUNCHER无MAIN:

结果:同第一种情况一样

 

第三种,有多个Activity同时有MAIN和LANUCHER

AndroidMainfest.xml代码示例:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

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

    <activity android:name=".SecondActivity"
        android:label="SecondActivity">
        <intent-filter tools:ignore="AppLinkUrlError">
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

 结果:桌面有两个程序的图标。


测试时需要注意,在两个Activity中要分别设置label(应用程序的名称),否则只会生成一个图标。另外,在两个Activity都没有添加DEFAULT或者都添加了DEFAULT的前提下,两个Activity在AndroidMainfest.xm中先后顺序决定了程序首先启动的是哪一个Activity。

 

现在再来解释下DEFAULT对启动顺序的影响,如果两个Activity中有一个添加了一个DEFAULT(前提是两个Activity都添加了MAIN和LAUNCHER),那么无论哪个Activity在前,都会先执行添加了DEFAULT的那个Activity,假如两者都添加DEFAULT,那么哪个首先执行取决于顺序。不信的朋友可以自己试试。

 

Android系统的Intent的解析规则如下:

1. 一个意图Intent至多只会包含一个action和多个category,而一个intent filter 却可以包含多个action和多个category。在intent与Intentfilter匹配时,要求在intent中出现的action和所有category必须全部包含在intent filter中。

 

2. Intent的数据data中Uri的每个子部需要与Intent filter<data>标签中的属性进行匹配,如果<data>标签指定了协议,主机名,路径,端口等,则需要完全匹配,任何不匹配的intent都将会被过滤掉。

 

3. 如果intent filter匹配的结果多于一个,则用户来进行选择。

 

4. 在 Intent中,最多指定一个“action”,而在intent filter中则可以指定多个action,只要intent filter中的action包含intent中的action,该intent就可以通过,未指定action的intent可以满足intent filter指定的任意的action。

5. 一个activity可以包含多个intent-filter,对于包含多个intent-filter的activity,只要其中一个intent-filter被intent匹配则这个activity就可以被启动。

 

解析规则这么多,总的来说就一句话,intent通过代码设置的条件,无论是action还是category,只要是intent-filter的子集,那么就可以匹配,如果有data的话,需要intent通过代码设置的data和intent-filter中data的内容完全一致(协议,主机名,路径,端口等)才可以匹配。

<think>首先,用户的问题是:“我想了解启动service时intent-filter的相关信息 请问启动service时intent-filter的作用、使用方法及相关注意事项”。这基于之前提供的引用。 回顾引用: - 引用[1]:警告使用显式Intent启动Service,避免Intent过滤器,因为安全风险。 - 引用[2]:描述启动Service的方法(startService())和生命周期。 - 引用[3]:解释了IntentFilter的定义和属性设置。 - 引用[4]:区分显式和隐式Intent,隐式Intent需要解析。 - 引用[5]:展示了使用隐式Intent启动Activity的例子(分享功能),但提到的是Activity,不是Service。 用户聚焦在Service的intent-filter上,所以我需要基于这些引用构建回答。 关键点: - **作用**:intent-filter用于Service,允许Service通过隐式Intent被启动。它定义了Service能响应哪些Intent操作。 - **使用方法**:在Manifest文件中为Service添加<intent-filter>元素,指定action等属性。 - **注意事项**:引用[1]强烈建议使用显式Intent启动Service,避免使用intent-filter,以避免安全风险。引用[4]也提到隐式Intent需要解析,可能导致不确定的行为。 从引用[1]:“为了确保应用的安全性,启动 Service 时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。使用隐式 Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应 Intent,且用户无法看到哪些服务已启动。” 这直接相关。 所以,在回答中,我应该强调安全性问题。引用[5]是关于Activity的分享功能,使用隐式Intent,但Service不同;引用提到Service时,应优先考虑显式Intent。 回答结构: 1. **作用**:解释intent-filter在Service上下文中的作用。 2. **使用方法**:描述如何在AndroidManifest.xml中添加intent-filter。 3. **注意事项**:重点讨论安全风险和最佳实践,基于引用[1]。 确保回答清晰、中文、结构良好。用户要求“回答结构清晰,帮助用户逐步解决问题”,所以我会分部分。 最后,系统指令要求“生成相关问题”,所以我需要在末尾添加相关问题。 引用标识:在回答中引用段落时,自然地添加[^1]等。例如,提到安全建议时用[^1]。 完整回答大纲: - 介绍intent-filter的基本概念。 - 作用:允许Service响应隐式Intent- 使用方法:示例代码在Manifest中。 - 注意事项:强调显式Intent的重要性,安全风险[^1]。 - 相关问题。 生成相关问题: 1. 什么是显式Intent和隐式Intent的区别? 2. 如何在Android中安全地启动Service? 3. 隐式Intent在Activity和Service中的应用场景有何不同? 确保LaTeX语法正确:用户提到数学表达式,但这里可能不涉及,所以注意避免不必要的数学部分。如果有变量,用$...$格式。 最终回答: - 用中文。 - 引用适当。 - 相关问题部分。 </think>### Service启动时的Intent-Filter详解 在Android开发中,启动Service时使用的intent-filter是一个关键概念。它允许Service通过隐式Intent被启动,但根据最佳实践和安全考虑,开发者通常应避免使用这种方式。下面我将基于您提供的引用内容,逐步解释intent-filter的作用、使用方法及相关注意事项,确保回答真实可靠。 #### 1. **Intent-Filter的作用** - **主要功能**:Intent-filter用于定义Service能响应哪些隐式Intent。它通过指定`<action>`、`<category>`或`<data>`等属性,告知Android系统该Service可以被匹配特定Intent的操作调用。例如,如果Service声明了某个action的intent-filter,任何发送该action的隐式Intent都可能启动该Service[^3][^4]。 - **应用场景**:尽管intent-filter在Activity中常见(如分享功能[^5]),但在Service中使用较少。理论上,它可以用于实现通用后台任务(如文件下载或音乐播放),但这种做法增加了安全风险。引用[4]强调,隐式Intent需要Android系统解析匹配组件,这可能引入不确定性[^4]。 #### 2. **Intent-Filter的使用方法** - **步骤说明**:要为Service添加intent-filter,需在AndroidManifest.xml文件中定义。以下是典型的使用方法: - 在`<service>`元素内添加`<intent-filter>`子元素。 - 指定必要的属性,如`<action>`(定义Service响应的操作)、`<category>`(默认为`DEFAULT`类别)或`<data>`(指定数据类型或URI)。 - 示例代码: ```xml <service android:name=".MyService"> <intent-filter> <action android:name="com.example.project.START_DOWNLOAD" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/pdf" /> </intent-filter> </service> ``` 此代码允许任何隐式Intent(action为`com.example.project.START_DOWNLOAD`且数据类型为PDF)启动`MyService`[^3][^4]。 - **启动Service**:开发者可以通过`startService()`方法发送隐式Intent来触发Service。例如: ```java Intent intent = new Intent("com.example.project.START_DOWNLOAD"); intent.setDataAndType(Uri.parse("file://path/to/file.pdf"), "application/pdf"); startService(intent); ``` 这将匹配上述intent-filter,并调用Service的`onStartCommand()`方法执行任务[^2][^4]。 #### 3. **相关注意事项** - **安全风险**:使用intent-filter启动Service存在严重安全隐患。引用[1]明确指出:“启动 Service 时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。使用隐式 Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应 Intent,且用户无法看到哪些服务已启动。”[^1] 原因包括: - **不确定性**:隐式Intent可能匹配多个Service(包括恶意应用),导致未授权访问或数据泄露[^1][^4]。 - **用户不可见**:用户无法感知哪个Service被启动,增加了隐私风险[^1]。 - **最佳实践**: - 优先使用**显式Intent**启动Service:显式Intent直接指定目标Service类名(如`Intent(context, MyService.class)`),避免使用intent-filter。这确保了精确控制和安全隔离[^1][^2]。 - 避免intent-filter:除非有特殊需求(如系统级共享服务),否则不要在Service中声明intent-filter。引用[5]展示了隐式Intent在Activity中的应用(如分享功能),但Service场景不同,风险更高[^5]。 - 生命周期管理:即使使用intent-filter,Service的生命周期(如`onStartCommand()`和`onDestroy()`)仍需妥善处理,以防资源泄漏[^2]。 - **其他考虑**:如果必须使用隐式Intent,应严格限制`<action>`和`<data>`属性,并在代码中添加权限检查。但总体上,Android官方推荐显式方式作为默认选择[^1][^4]。 #### 总结 Intent-filter在Service中的作用是支持隐式Intent启动,但基于安全原则,开发者应优先使用显式Intent。确保在Manifest中谨慎定义intent-filter,并始终评估风险。如果您的场景涉及共享功能(类似引用[5]),建议参考Activity-based的实现,而非Service[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胖墩有点瘦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值