一.Intent的介绍
Intent的英文翻译是“意图、目的、意思、含义“,Android通过Intent来启动Android应用程序中的三个重要组件Activity、Service、BroadcastReceiver,使用Intent可以减少代码、组件之间的耦合。
为什么要使用Intent呢?
假如ActivityA需要启动另外一个ActivityB,为什么不直接使用类似startActivity(Class ActivityB)的方式?
实际上,使用类似startActivity(Class ActivityB)的方式启动另外一个Activity,反而违背了Android的理念,Android使用Intent来封装程序的"调用意图",不管程序想启动一个Activity也好,想启动一个Service也好,又或者启动一个BroadcastReceiver也罢,Android使用统一的Intent对象来封装这种"启动意图",很明显使用Intent提供了一致的编程模型。
Intent调用组件分为显示调用和隐式调用
调用就像找女朋友,显示调用就是要找“某某”做女朋友,隐式调用就是要找“身材好的”,“皮肤白的”做女朋友。
显式调用正常的写法
ComponentName cName = new ComponentName(MainActivity.this,SecondActivity.class);
Intent intent = new Intent();
Intent.setComponent(cName);
startActivity(intent);
简便的写法
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
隐式调用
Intent启动Activity的方法
startActivity(Intent intent)
srartActivityForResult(Intent intent,int requestCode)
Intent启动Service的方法
ComponentName startService(Intent intent)
boolean bindService(Intent intent,ServiceConnection con,int flags)
Intent启动BroadcastReceiver的方法
sendBroadcast(Intent intent)
sendBroadcast(Intent intent,String receiverPermission)
sendOrderedBroadcast(Intent intent,String receiverPermission,BroadcastReceiver resultReceiver,Handle scheduler,int initialCode,String initialData,Bundle initialExtras)
sendOrderedBroadcast(Intent intent,String receiverPermission)
sendStickyBroadcast(Intent intent)
sendStickyOrderedBroadcast(Intent intent,BroadcastReceiver resultReceiver,Handler scheduler,int initialCode,String initialDate,Bundle initialExtras)
按照SDK上的描述,一个Intent对象就是一些信息的集合.因为它是一个操作的抽象,有如下一些属性:
Component
指定Intent的目标组件的类名称.通常Android会根据Intent中包含的其它属性的信息,比如Action 、Category 、Data、Type进行查找,最终找到一个与之匹配的目标组件.但是,如果Component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程.指定了这个属性以后,Intent的其它所有属性都是可选的,这就是显示调用
ComponentName cName = new ComponentName(MainActivity.this,SecondActivity.class);
Intent intent = new Intent();
Intent.setComponent(cName);
startActivity(intent);
Action
Action就是一个普通的字符串,表示Intent要完成的一个抽象"动作",当然一个Action有主动也有被动,比喻在Broadcast中就是一些被动Action,其实被动Action从接收方的角度来说,有点类似于Event的感觉.Android里面对Action默认定义了一些通用的Action.按照SDK文档中的建议,一个Action实际上不仅仅是一个参数与返回值的问题,它实际上跟后面的Data和Extras字段有很多关联.用得好的话,可以带来很多便利
也可以自定义动作,自定义的动作在使用时,需要加上包名作为前缀,如"org.stone.projectName.ACTION_NAME",并可定义相应的Activity来处理我们的自定义动作,Android鼓励使用缺省的一些Action,不建议过多的自定义的Action。
一个Intent最多只能有一个Action属性Intent设置Action属性setAction(String actionName)。
注意每个Action的常量前都少了android.intent.action.
Category
按照SDK的描述,是指关于接收这个Intent的这种组件的附加信息.系统定义的Category与Action结合具有特定的含义,不可以乱用,而且一般情况下都是与Action一起结合使用。一个Intent对象可以有任意个CategoryIntent与Category相关的方法,例如:
addCategory(String categoryName)
增加一个Category
removeCategory(String categoryName)
删除一个Category
Set<String> getCategories()
获取所有的Category
注意
Category属性不能单独存在,必须配合Action属性一起使用
即使是使用了自己的Category,系统默认的Category也不能省略配置<categoryandroid:name="android.intent.category.DEFAULT"/>
注意每个Category的常量前都少了android.intent.category.
Data
执行动作要操作的数据,一般由一个Uri变量来表示
不同的Action需要结合不同的Data来一起使用,才能达到想要的结果.Data属性就是Action所需要数据的Uri和MIME类型.因此,设置这个属性时需要根据你的Action来决定.这里常用的方法是setData或者setType.因此,这里所说的Data属性实际上还包括Type属性.
Type
显式指定Intent的数据类型MIME
多用途互联网邮件扩展
Multipurpose Internet Mail Extensions
很多情况下,Data类型可在Uri中找到,比如content:开头的URI,表明数据由设备上的ContentProvider提供.但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导.
MIME类型有2种形式
单个记录的格式
vnd.android.cursor.item/vnd.yourcompanyname.contenttype
如
content://com.example.transportationprovider/trains/122
(一条列车信息的Uri)的MIME类型是vnd.android.cursor.item/vnd.example.rail
多个记录的格式
vnd.android.cursor.dir/vnd.yourcompanyname.contenttype
如
content://com.example.transportationprovider/trains
(所有列车信息)的MIME类型是vnd.android.cursor.dir/vnd.example.rail
Extra
Extras算是Intent的附加信息,有没有该对象,并不影响Intent的启动,类似于往要启动的Activity传递参数,可以通过Bundle对象来完成.
Flag
Activity和Task(栈)的关系
Task就像一个容器,而Activity就相当与填充这个容器的东西,第一个东西(Activity)则会处于最下面,最后添加的东西(Activity)则会在最低端.从Task中取出东西(Activity)则是从最顶端取出,也就是说最先取出的是最后添加的东西(Activity),以此类推,最后取出的是第一次添加的Activity,而Activity在Task中的顺序是可以控制的,那则在Activity跳转时用到Intent的Flag属性.
Intent包含如下一些Flag值
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
如果Activity在Task存在,拿到最顶端,不会启动新的Activity
Intent.FLAG_ACTIVITY_CLEAR_TOP
如果Activity在Task存在,将Activity之上的所有Activity结束掉
Intent.FLAG_ACTIVITY_NEW_TASK
默认的跳转类型,将新的Activity放到一个Task中
Intent.FLAG_ACTIVITY_NO_HISTORY
新Activity将不在Task中保留.用户一离开它,这个Activity就关闭了
Intent.FLAG_ACTIVITY_NO_ANIMATION
在启动Activity的时候不要过渡动画