之前写过一篇Intent的博客,主要说了一下隐式意图。 传送门:《Android -- Intent

Intent对象构成

Component name、Action、Data、Category、Extras、Flags

Component name

Component name即组件名称,是要处理这个Intent对象的组件名称。

组件名称对象由ComponentName类来封装,组件名称包含包名称和类名称,被声明在AndroidManifest.xml文件中。

组件名称通过 setComponent(),setClass(),setClassName()设置,通过getComponent()获取。

需要注意的是Component name是一个可选项,如果被设置,那么Intent对象就显式指定了要转向的组件,如果没有被设置,则Intent对象需要根据其他信息进行筛选查找。

Action

Action是指Intent要完成的动作,是一个字符串常量。

Intent类中有很多预定义的常量,为了一些通常的动作;还有一些定义在Android API的其他地方。也可以自己定义Action常量,自定义的常量需要加上你的应用的包名作为前缀。

Action在很大程度上决定了Intent的其他部分是如何构造的,尤其是 data 和 extras域。(就好像函数名会决定着参数值和返回值一样。)所以Action的名字应该尽可能具体,并且它们应该和Intent中的其他域紧密结合。

使用 setAction() 和 getAction()来设置和读取Action属性。

Data

Data属性是执行动作的URI和MIME类型,不同的动作有不同的数据规格。

比如,Action是ACTION_EDIT时,数据域将是文档的URI;Action是ACTION_CALL时,数据域是 tel: URI ,带有要拨打的电话号码;如果Action是 ACTION_VIEW,则数据域是http: URI。

当匹配intent和能够处理intent所带的数据的组件时,知道数据类型(MIME类型)是很重要的。比如,一个展示图像的组件不应该被叫去播放一个音频。

很多情况下,从URI可以看出数据类型,比如content: URIs,表示数据是在设备上,但是是由content provider控制。

数据类型也可以显式指定,比如setData()方法指定数据为URI,setType() 指定为MIME type,setDataAndType() 指定它既为URI又为MIME type。读取的时候URI用getData(),MIME type用getType()。

Category

Category是一个字符串,提供了额外的信息,有关于能够处理这个Intent对象的组件种类。

一个Intent对象中可以包含任意数量的category描述信息。

与category相应的方法有添加addCategory()、移除removeCategory() 和获取所有category getCategories() 。

Extras

传递给Intent的额外数据,以Bundle的形式定义,就是一些键值对。就好像一些动作和特定的数据URI对应,一些动作和特定的extras对应。

比如ACTION_TIMEZONE_CHANGED intent对象有一个 "time-zone"的extra来确认新的时区;

ACTION_HEADSET_PLUG有一个"state" extra表示耳机是否插入,还有一个 "name" extra关于耳机类型;

如果你要设计一个SHOW_COLOR动作,那么extra中应该包含颜色值。

Intent对象有一系列的putXXX()函数用于放入各种数据类型,相应的也有一系列的getXXX()函数用于读取数据。

实际上,数据可以被作为一个Bundle对象被使用,利用 putExtras() 和 getExtras() 方法。

Flags

各种类型的Flag。很多是用来指定Android系统如何启动activity,还有启动了activity后如何对待它。所有这些都定义在Intent类中。

Intent filter

为了告知系统哪一些隐式的intent可以被处理,activity,service和broadcast receiver拥有一个或多个intent filter。

每一个filter描述了组件的一种能力,和一个这个组件愿意接收的intent的集合。它实际上的效果是过滤了特定类型的intent,将不想要的intent排除在外,但是也只能排除不想要的隐式类型的intent,显式的intent可以直接被传递到它的目标对象,不管它包含什么,filter是不会被查询的。

但是一个隐式的intent只能在能够通过这个组件的filter之一的时候传递到这个组件。

一个组件对于它可以做的各种工作拥有各种独立的filter。

一个intent filter就是一个IntentFilter类的对象,但是,由于Android系统必须在启动一个组件前知道它的能力,intent filter通常不是在Java代码中建立的,而是在应用的manifest文件中(AndroidManifest.xml),作为<intent-filter> 元素。

一个例外的情况就是broadcast receiver的filter,它们是通过Context.registerReceiver()方法动态注册的,它们将会被直接作为IntentFilter对象创建。

当一个Intent对象和一个intent filter进行测试时,Intent对象中只有三个方面会被参考:

  • action
  • data(URI和数据类型)
  • category

当决议那个组件接收intent时,extras和flags是不起作用的。

一个filter含有与Intent对象中的action,data,category平行的域,一个隐式的intent将会测试所有这三个域。

为了传递到含有filter的组件,intent对象必须通过所有这三个测试。

如果其中的一个测试失败了,Android系统将不会把这个intent对象传递到这个组件,至少不会是基于那个filter的组件

然而,由于一个组件可以拥有多个intent filter,一个intent对象可能没有通过其中的一个filter,但是它可能通过另一个。

Code Action

在manifest中,<intent-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>

一个filter可以列出多个动作,这个列表不能为空,即一个filter应该至少包含一个动作否则它将会阻挡任何的intent

为了通过这个测试,intent对象中指定的动作应该和列出的动作之一匹配,如果intent对象或filter没有指定动作,结果将会如下:

1.如果是filter没有列出任何动作,没有东西让intent来匹配,所以所有的intent都将会在测试中失败。没有任何intent可以通过这个测试。

2.另一方面,如果一个intent对象没有指定动作,那它将自动地通过测试。(只要filter中含有至少一个动作)。

Code Category

<intent-filter>也将分类作为其子元素列出,如

<intent-filter . . . >
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
. . .
</intent-filter>

如果一个intent对象想通过category,那么在intent对象中的每一个分类都必须和filter中的一个分类匹配。

Filter可以列出多余的分类,但是不能忽略intent中的任何一个分类。

原则上来说,一个不带有任何category的intent对象应该总是能够通过测试。但是有一个例外,Android将所有传入startActivity()方法的隐式intent看作它们至少含有一个category: "android.intent.category.DEFAULT" (the CATEGORY_DEFAULT constant)。

所以,想要收到隐式intent对象的activity必须在它们的intent filter中包含 "android.intent.category.DEFAULT" 。(包含"android.intent.action.MAIN" 和 "android.intent.category.LAUNCHER"的filter是一个例外,它们可以包含"android.intent.category.DEFAULT",但是它们没有必要这样做。)

Code Data

和动作和分类一样,数据也是作为子标签出现,也可以不出现或出现多次。如:

<intent-filter . . . >
<data android:mimeType="video/mpeg" android:scheme="http" . . . />
<data android:mimeType="audio/mpeg" android:scheme="http" . . . />
. . .
</intent-filter>

每一个<data>元素可以指定一个URI和一个数据类型(MIME media type)。

每一个URI包含下列属性:scheme, host, port, path    (如:scheme://host:port/path)

当一个intent对象中的URI和filter中的URI比较时,它仅仅和filter中实际提到的URI部分进行比较。比如,一个filter仅仅指定了scheme,那么所有有那个scheme的URI都和这个filter匹配。

Filter中的path可以包含通配符(wildcards)。

<data>元素中的type属性指定了数据的MIME type,它在filter中比URI更常见。

Intent对象和filter都可以使用通配符*去表示子类型,如"text/*" or "audio/*" — indicating any subtype matches。

数据测试需要测试URI和数据类型,规则如下:

a.一个intent对象,如果既不包含URI,也不包含数据类型,那么仅当filter也都不包含时,可以通过测试。

b.如果一个intent对象仅包含一个URI,不包含数据类型,(并且从URI中也不能得到数据类型),那么仅当这个URI和filter中的URI匹配,并且filter中也不包含数据类型时,可以通过测试。(This will be the case only for URIs like mailto: and tel: that do not refer to actual data.)

c.一个intent对象如果只包含数据类型不包含URI,那么仅当filter包含同样的数据类型并且不包含任何URI时可以通过测试。

d.一个intent对象如果同时包含URI和数据类型,(或者是可以从URI中推断出的数据类型),那么仅当它的数据类型和filter中的一个数据类型匹配时它可以通过数据类型部分的测试,如果要通过URI部分的测试,一种情况是它的URI和filter中的匹配,另一种情况是intent包含有content:或者file:URI而filter不包含URI。换句话说,如果一个filter只指定了数据类型,组件是预定义地支持content:或者file:数据的。

  如果一个intent可以通过多个activity或service的filter,用户将被询问,到底要选择哪个组件来启动;如果没有目标被发现,将会产生一个异常。

我是天王盖地虎的分割线

Android -- 再来一发Intent的更多相关文章

  1. Android -- 再来一发Notification

    之前写过一个Notificaiton的文章,用上面的方式去操作也是OK的,但是到后面的SDK之后,有些方法被弃用,甚至我到SDK23的时候,我发现有些方法直接没了,所以在这里重新写一下最新的用法. h ...

  2. Android -- 再来一发Json

    之前写过一篇Json的博客,当时用的是Gson包来解析的,这次来此自带的org.json来解析.传送门:<Gson解析复杂Json数据> JSON的结构 (1) Name/Value Pa ...

  3. Android安全之Intent Scheme Url攻击

    0X01 前言 Intent scheme url是一种用于在web页面中启动终端app activity的特殊URL,在针对intent scheme URL攻击大爆发之前,很多android的浏览 ...

  4. Android学习之 Intent详解

    一. Intent 作用 Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯.比如说调用startActivity()来 ...

  5. Android中的Intent详解

    前言: 每个应用程序都有若干个Activity组成,每一个Activity都是一个应用程序与用户进行交互的窗口,呈现不同的交互界面.因为每一个Acticity的任务不一样,所以经常互在各个Activi ...

  6. Android 消息广播Intent传递数据

    1.创建布局文件activity_broadcast.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk ...

  7. Android总结篇——Intent机制详解及示例总结

         最近在进行android开发过程中,在将 Intent传递给调用的组件并完成组件的调用时遇到点困难,并且之前对Intent的学习也是一知半解,最近特意为此拿出一些时间,对Intent部分进行 ...

  8. Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面

    现在开发中的功能需要直接跳转到拨号.联系人.短信界面等等,查找了很多资料,自己整理了一下. 1.跳转到拨号界面,代码如下: 1)直接拨打 Intent intentPhone = new Intent ...

  9. 【转】Android Activity和Intent机制学习笔记----不错

    原文网址:http://www.cnblogs.com/feisky/archive/2010/01/16/1649081.html Activity Android中,Activity是所有程序的根 ...

随机推荐

  1. Scrapy 笔记(二)

    一个scrapy爬虫知乎项目的笔记 1.通过命令创建项目 scrapy startproject zhihucd zhihuscrapy genspider zhihu www.zhihu.com(临 ...

  2. 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 xor (根号分治)

    xor There is a tree with nn nodes. For each node, there is an integer value a_ia​i​​, (1 \le a_i \le ...

  3. FastReport.Net使用:[28]数据合并

    基础数据 1.拖动数据源中的数据列到报表设计器中,获得一张简单的报表. 2.下面使用两种方法将期中考试和期末考试的成绩合并到一行显示 合并数据(分组方法) 1.按学生名字和科目来进行分组,成绩文本框咱 ...

  4. Hibernate lazy(延迟加载)

    Hibernat加载策略有两种,分别为即时加载和延迟加载(懒加载或者lazy),get使用的是即时加载,使用get获取数据时会立即查找(会先去缓存查找,如果缓存中没有找到,才会去数据库中查找),而lo ...

  5. 51nod1394 差和问题 值域线段树

    水题..... 插入一个值$v$时,对于$[0, v - 1]$和$[v + 1, inf]$的点分别考虑就行了 删除相当于减去插入的贡献 用动态开点线段树卡点常数就过去了 复杂度$O(n \log ...

  6. BNU校赛总决赛J 小白兔小灰兔 相交计算几何模板

    J 小白兔小灰兔 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K Special Judge, 64bit IO Format: %lld 题目描述 ...

  7. redis的原子性

    什么是原子性操作 在多进程(线程)访问共享资源时,能够确保所有其他的进程(线程)都不在同一时间内访问相同的资源,(要么完全执行,要么完全不执行) 简单描述 有个变量X=0,要进行+1操作,步骤如下: ...

  8. nginx hello模块代码

    // ngx_http_mytest_module.c #include "ngx_core.h" #include "ngx_string.h" #inclu ...

  9. 2015编程之美 初赛第一场C题 质数相关 二分图的最大匹配

    质数相关 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://hihocoder.com/contest/msbop2015round2a/prob ...

  10. Android 动画——Layout Animations布局动画

    Layout Animations主要使用LayoutTransition为布局的容器设置动画,当容器中的视图层次发生变化时存在过渡的动画效果. LayoutTransition This class ...