概述
Intent是一个动作的完整描述,包含了产生组件、接收组件和传递数据信息。并且,Intent利用消息实现应用程序之间的交互机制,这种消息描述了应用中一次操作的动作、数据以及附加数据,系统通过该Intent的描述负责找到对应的组件,并将Intent传递给调用的组件,完成组件的调用。
Intent属性
Intent由动作、数据、分类、类型、组件和扩展信息等内容组成,每个组成都由相应的属性进行表示,并提供设置和获取相应属性的方法。如下图所示:

Action属性
Action属性用于描述Intent要完成的动作,对要执行的动作进行简单的描述。Intent类定义了一系列Action属性常量,用来标识一套标准动作,如ACTION_CALL(打电话)、ACTION_EDIT(编辑)等。
注意:action只是一个普通的字符串,代表Intent要完成的一个抽象“动作”,而具体由哪个组件来完成,Intent并不负责!就是仅仅知道会有这个动作,谁来完成这个动作那就要交给Intent-filter来进行筛选了!根据我的理解,这个Intent应该就是起到一个中介的作用吧!
以下是一些action属性常量:

Data/Type属性
Data属性是执行动作的URI和MIME类型。通常用来向Action属性提供操作的数据,接受一个URI对象,URI的格式:scheme://host:post/path 参数依次为:协议头、主机、端口、路径;
Type通常用于指定Data所指定的Uri对应的MIME类型,比如能够显示图片数据的组件不应该用来播放音频文件,可以是自定义的MIME类型,只要符合abc/xyz格式的字符串就可以了。
Data常量如下:

Action和Data匹配使用,不同的Action由不同的Data数据指定

Category属性
Category属性指明一个执行Action的分类。
**注意:同样是普通的字符串,Category用于为Action提供额外的附加类别信息,两者通常结合使用,一个Intent对象只能有一个Action,但是能有多个Category。**
Component属性
该属性用于指明Intent目标组件的类名称。通常Android会根据Intent包含的其他属性的信息,比如Action、 Data/Type、 Category 进行查找,最终找到一个与之匹配的目标组件。但是,如果指定了Component这个属性,Intent 则会直接根据组件名查找到相应的组件,而不再执行上述查找过程。指定Component属性后, Intent的其他属性都是可选的。
Extra属性
该属性用于添加附加信息,通常用于多个Action之间的数据交换,Extras属性是一个Bundle对象,通过键值对进行数据存储。下面介绍如何利用Intent在activity之间传递数据部分会详细介绍并举例实现。
Flag属性
表示不同来源的标记,flag可以指导系统以何种方式启动一个activity、是否将启动的activity放在该应用的任务栈中等等。常用flags如下:
FLAG_ACTIVITY_NEW_TASK:设置这个标记位,是为 Activity 指定 “singleTask” 启动模式,它的作用和在清单文件中指定该启动模式的效果一样。
FLAG_ACTIVITY_SINGLE_TOP:设置这个标记位,是为 Activity 指定 “singleTop” 启动模式,它的作用和在清单文件中指定该启动模式的效果一样。
FLAG_ACTIVITY_CLEAR_TOP:具有此标记位的 Activity,在它启动时,在同一个任务栈中所有位于它上面的 Activity 都要出栈。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有这个标记的 Activity 不会出现在历史 Activity 的列表中。它等同于在清单文件中指定 Activity 的属性android:excludeFromRecents=“true”
Intent的类别
根据Intent寻找目标组件时所采用的方式不同,可以将Intent分为两类:显示Intent和隐式Intent。
显示Intent
显示Intent 通过直接指定组件来实现,常用方法有setComponent(、 setClassName0或setClass(),如下示例:
1 | findViewById(R.id.open).setOnClickListener(new View.OnClickListener() { |
注意:显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,因此,显式Intent更多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。
隐式Intent
隐式Intent,这种方式通过Intent Filter过滤实现,过滤时通常根据Action、Data和Category属性进行匹配查找。Android提供了两种生成Intent Filter的方式: 一种是通过IntentFilter类生成;另一种通过在配置文件AndroidManifest.xml中定义
注意:它更广泛地用于在不同应用程序之间传递消息,由于没有明确的目标组件名称,所以必须由Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。
一个通过隐式Intent启动不同应用程序的activity的例子:
- 首先要在一个应用程序中先设置好action

- 然后在另一个应用程序里通过完整的action的name来启动。
- 启动时要将两个应用程序都打开。


- 在另一个activity上禁止启动的属性android:exported=”false”,则可以拒绝启动,并抛出异常,这时候可以捕获异常并弹出提示。
利用Intent在Activity之间传递数据
Intent传递简单数据
可以直接通过调用Intent的putExtra()方法存入数据,然后在通过getIntent()获得Intent后调用getXxxExtra获得 对应类型的数据;传递多个数据的话,可以使用Bundle对象作为容器,通过调用Bundle的putXxx先将数据存储到Bundle中,然后调用Intent的putExtras()方法将Bundle存入Intent中,然后调用getExtras()获得Bundle容器,最后调用其getXXX获取对应的数据!
举例如下:
传递单个数据:

在另一个activity中先获取intent然后在获取数据

传递多个数据:
利用Bundle传递多个数据:

在另一个activity中先获取Intent再获取Bundle


Intent传递数组
和以上传递数据类型差不多,直接举例如下:

另一个activity里面获取,直接利用日志打印。


Intent传递集合
List:
主activity写入集合

子activity获取并打印


Intent传递对象
Serializable实现:
①业务Bean实现:Serializable接口,写上getter和setter方法
②Intent通过调用putExtra(String name, Serializable value)传入对象实例 当然对象有多个的话多个的话,我们也可以先Bundle.putSerializable(x,x);
③新Activity调用getSerializableExtra()方法获得对象实例: eg:Product pd = (Product) getIntent().getSerializableExtra(“Product”);
④调用对象get方法获得相应参数。
举例如下:
首先,创建一个User类,实现Serializable接口,写上getter和setter方法。

然后在主activity中设置要传递的对象。

最后在子activity中获取该对象。


Parcelable实现:
①业务Bean继承Parcelable接口,重写writeToParcel方法,将你的对象序列化为一个Parcel对象;
②重写describeContents方法,内容接口描述,默认返回0就可以
③实例化静态内部对象CREATOR实现接口Parcelable.Creator
④同样式通过Intent的putExtra()方法传入对象实例,当然多个对象的话,我们可以先 放到Bundle里Bundle.putParcelable(x,x),再Intent.putExtras()即可
说明:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射 成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面, 在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的 顺序和读的顺序必须一致。
举例如下:
首先,修改User类,实现Parcelable接口,并添加以下方法:

在主activity中设置对象,设置对象与Serializable设置一样:

在子activity中获取,注意获取方式不同


两种对象序列化方式的比较:
1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的 持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable。
4)Parcelable是android特有的序列化API,Serializable是java的序列化技术。
Intent返回一个activity数据给另一个activity
获取另一个activity返回的数据时,启动另一个activity方法要改成startActivityForResult(i, 0);其中i是指的Intent,0是请求状态码,用来识别第二个activity传回的值

在第二个activity中用setResult(1,i);准备好要返回的数据,并通过finish()方法结束改activity,

然后返回到第一个activity中执行会调回函数onActivityResult


利用Intent调用系统组件
个人理解利用Intent调用系统组件实际上是利用了隐式Intent匹配组建的功能,通过匹配Action、data、category来打开对应的组件,如果有多个,则会出现选择列表来选择。
打开系统联系人


打电话


发短信


打开浏览器


播放音乐

