安卓API指南之Intent 和 Intent 过滤器

本系列的文章全部为学习摘要,不偏重各种细节展示,更多的是安卓体系重要节点的罗列,并适时加入少量自己的理解分析,以便能快速的回顾安卓体系结构和那些重要的技术点。

Intent 是一个消息传递对象,您可以使用它从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件之间的通信,但其基本用例主要包括以下三个:

  • 启动 Activity:通过将 Intent 传递给 startActivity(),您可以启动新的 Activity 实例。Intent 描述了要启动的 Activity,并携带了任何必要的数据。如果您希望在 Activity 完成后收到结果,请调用 startActivityForResult()。在 Activity 的 onActivityResult() 回调中接收结果。

  • 启动服务:通过将 Intent 传递给 startService(),您可以启动服务执行一次性操作(例如,下载文件)。如果服务旨在使用客户端-服务器接口,则通过将 Intent 传递给 bindService(),您可以从其他组件绑定到此服务。

  • 传递广播:通过将 Intent 传递给 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast(),您可以将广播传递给其他应用。

Intent 分为两种类型:

  • 显式 Intent:按名称(完全限定类名)指定要启动的组件。
  • 隐式 Intent :不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它。Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件。

Intent 过滤器是应用清单文件中的一个表达式,它指定该组件要接收的 Intent 类型。 为了确保应用的安全性,启动 Service 时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。

构建 Intent–Intent 中包含的主要信息如下:

  • 组件名称 ComponentName:
    可选项,但也是构建显式 Intent 的一项重要信息。如需在应用中启动特定的组件,则应指定该组件的名称。可以使用 setComponent()、setClass()、setClassName() 或 Intent 构造函数设置组件名称。

  • 操作Action
    指定要执行的通用操作(例如,“查看”或“选取”)的字符串。系统自带了一些操作,比如ACTION_VIEW和ACTION_SEND;若要定义自己的操作,请确保将应用的软件包名称作为前缀。 例如:
    static final String ACTION_TIMETRAVEL = “com.example.action.TIMETRAVEL”;

  • 数据Data和类型MIME
    引用待操作数据和/或该数据 MIME 类型的 URI(Uri 对象)。提供的数据类型通常由 Intent 的操作决定。要仅设置数据 URI,请调用 setData()。 要仅设置 MIME 类型,请调用 setType()。如有必要,您可以使用 setDataAndType() 同时显式设置二者。注意 setData() 和 setType(),会互相抵消彼此的值。

  • 类别Category
    一个包含应处理 Intent 组件类型的附加信息的字符串。 您可以将任意数量的类别描述放入一个 Intent 中,但大多数 Intent 均不需要类别。您可以使用 addCategory() 指定类别。当不指定时,默认有CATEGORY_DEFAULT类别。

  • 附加数据Extra
    携带完成请求操作所需的附加信息的键值对。传递的数据包括基本数据类型,String,实现序列化的数据和Bundle支持的数据。

  • 标志Flag
    在 Intent 类中定义的、充当 Intent 元数据的标志。 标志可以指示 Android 系统如何启动 Activity(例如,Activity 应属于哪个任务),以及启动之后如何处理(例如,它是否属于最近的 Activity 列表)。比如FLAG_ACTIVITY_CLEAR_TOP,代表启动新Activity时,会使任务栈中目标Activity之上的活动出栈。若栈里无目标,则新建目标,无其它效果。

处理Intent:
用户可能没有任何应用处理您发送到 startActivity() 的隐式 Intent。如果出现这种情况,则调用将会失败,且应用会崩溃。要验证 Activity 是否会接收 Intent,请对 Intent 对象调用 resolveActivity()。如果结果为非空,则至少有一个应用能够处理该 Intent,且可以安全调用 startActivity()。 如果结果为空,则不应使用该 Intent。

  • 要公布应用可以接收哪些隐式 Intent,请在清单文件中使用 元素为每个应用组件声明一个或多个 Intent 过滤器。每个 Intent 过滤器均根据 Intent 的操作、数据和类别指定自身接受的 Intent 类型。 仅当隐式 Intent 可以通过 Intent 过滤器之一传递时,系统才会将该 Intent 传递给应用组件。

  • 显式 Intent 始终会传递给其目标,无论组件声明的 Intent 过滤器如何均是如此。

Intent 解析
当系统收到隐式 Intent 以启动 Activity 时,它根据以下三个方面将该 Intent 与 Intent 过滤器进行比较,搜索该 Intent 的最佳 Activity.

  • Intent 操作
    要指定接受的 Intent 操作,Intent 过滤器既可以不声明任何 元素,也可以声明多个此类元素。要通过此过滤器,您在 Intent 中指定的操作必须与过滤器中列出的某一操作匹配。
  • Intent 数据(URI 和数据类型)
    要指定接受的 Intent 数据, Intent 过滤器既可以不声明任何 元素,也可以声明多个此类元素。每个 元素均可指定 URI 结构和数据类型(MIME 媒体类型)。 URI 的每个部分均包含单独的 scheme、host、port 和 path 属性:< scheme >://< host >:< port >/< path >。例如:content://com.example.project:200/folder/subfolder/etc
    在此 URI 中,架构是 content,主机是 com.example.project,端口是 200,路径是 folder/subfolder/etc。

作者: 刘咸尚

  • Intent 类别
    要指定接受的 Intent 类别, Intent 过滤器既可以不声明任何 元素,也可以声明多个此类元素。若要使 Intent 通过类别测试,则 Intent 中的每个类别均必须与过滤器中的类别匹配。反之则未必然,Intent 过滤器声明的类别可以超出 Intent 中指定的数量,且 Intent 仍会通过测试。

另外,PackageManager 提供了一整套 query…() 方法来返回所有能够接受特定 Intent 的组件。此外,它还提供了一系列类似的 resolve…() 方法来确定响应 Intent 的最佳组件。 例如,queryIntentActivities() 将返回能够执行那些作为参数传递的 Intent 的所有 Activity 列表,而 queryIntentServices() 则可返回类似的服务列表。这两种方法均不会激活组件,而只是列出能够响应的组件。 对于广播接收器,有一种类似的方法: queryBroadcastReceivers()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值