一、 Intent的介绍
Intent的中文意思是“意图、意向”,在Android中提供了Intent辅助组件之间进行交互。Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。
1.intent对象是传递给Context.startActivity()或Activity.startActivityForResult() 用于启动Activity或是让一个存在的Activity做些事情。如果用startActivityForResult启动Activity,在子Activit传递给Activity.setResult()来返回给Activity的信息。
2. Intent对象传递给函数来初始化一个service或是分发一个新的指令给一个正在进行的service,通过调用startService()和binderService方法启动。同样,intent传递给来建立一个在调用组件和目标service间的联系。如果一个service没有运行,它可以开始它。在Android 5.0在启动Services时,要显示启动,如果隐式启动会报错。
3.Intent可以传递给任何广播函数Context.sendBroadcast()、Context.sendOrderedBroadcast()、Context.sendStickyBroadcast()),intent被分派给所有感兴趣的广播接收者。在系统内核里有很多广播源,如果有需要,也可以选择接收。
二、Intent的属性
Intent对象是一个信息集合,包含了所有接收它的组件的信息,如携带的动作数据。Intent主要包含的信息如下:
1. 组件名
处理Intent的组件的名称,这个对象时包含了目标组件的全名,其在Manifest文件里设置组件名。组件的名称和在Manifest里设置的包名可以不一致,但是为了一致性,一般在Maneifest里设置的包名与实际包名一致。
组件的名字通过函数setComponent()、setClass()、setClassName()设置,通过函数读取getComponent()。
2. 动作
需要执行的动作的名称,即是Intent即将完成的动作,是一个字符常量。在SDK中定义了一些标准的Action动作常量如下:
Constant | Target component | Action |
ACTION_CALL | activity | 直接呼叫Data中所带的号码 |
ACTION_EDIT | activity | 系统根据不同的Data类型,通过已注册的对应Application编辑示数据 |
ACTION_MAIN | activity | Android Application的入口,每个Android应用必须且只能包含一个此类型的Action声明 |
ACTION_SYNC | activity | 同步数据到服务器. |
ACTION_BATTERY_LOW | broadcast receiver | 电量过低时发送广播 |
ACTION_HEADSET_PLUG | broadcast receiver | 耳机设备插入或拔出 |
ACTION_SCREEN_ON | broadcast receiver | 屏幕已打开 |
ACTION_TIMEZONE_CHANGED | broadcast receiver | Android系统的时间发生改变后发出带有此Action的广播(Broadcast) |
Intent里的动作是通过setAction()函数设置,通过getAction()函数读取。
3. 数据
数据的URI和MIME类型是Intent执行动作的数据配对基准,不同的Action对应不同的数据。如果动作是ACTION_CALL,数据域需要是一个带拨号的号码的tel: URI。如果动作是ACTION_VIEW数据域是http: URI,接收Activity需要调用并下载、显示URI引用的任何数据。
Intent和组件匹配是处理数据的能力,通过附加的URI信息可以判定数据的类型。例如播放音频文件的Action,就不能打开一个图片。
Intent通过setData()函数来指定一个URI,setType指定一个MEM类型。geetDataAndType()指定它是URI也是MIME类型。 getData()函数读取URI, getType()读取类型。
4. 类别
用于指定当前动作执行的环境,默认为CATEGORY_DEFAULT。
常用类别
CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。
CATEGORY_HOME:设置该组件为Home Activity。
CATEGORY_PREFERENCE:设置该组件为Preference。
CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。
CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。
CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。
在Intent里,addCategory() 放置一个intent里的类别,removeCategory()删除之前添加的,getCategories()获取当前所有的类别
5. 扩展
附加值对信息,这个键值会传递给Intent组件。一些动作和特定的数据URI匹配,一些和特定的扩展匹配。例如:一个ACTION_TIMEZONE_CHANGED intent有一个time-zone扩展域指明新的时区,ACTION_HEADSET_PLUG有一个state扩展的状态域指明耳机插入或拔出,name也有一个域来指明耳机的类型。如果你发明一个动作SHOW_COLOR ,颜色值在扩展键值对里设置。
intent有一系列的put...()函数来插入各种类型的数据和一系列get...()函数来获取各种类型的数据。对Bundle 对象,这些函数是并行的。事实上,长使用函数putExtras()和函数getExtras()来把数据作为Bundle读取、插入。例如序列化的实例类一般都是使用Budnle传递。
6. 标志
各种排序的标志,指示Android系统如何启动Activity(例如Activity属于哪个任务),启动后该如何处理,这些都是在Intent类里定义。
三、Intent的过滤器和安全性
Intent的过滤主要测试Intent对象的动作、数据、类别等三个方面,扩展和标志并不能确定哪个组件接收Intent。
intent过滤器 为了通知系统那个组件、Activity,service,广播过滤器可以处理intent,系统可以有多个intent过滤器。每个过滤器描述一个组件的能力,一个不处理的intent集合——仅仅是不处理隐式intent(这些不命名一个目标类)。一个显示intent总是分派给它的目标,不管它包含什么内容;过滤器这个时候不起作用。但是一个隐式intent仅当它可以通过一个组件的过滤器,次才被分派给这个组件。
动作测试 manifest文件里的<intent-filter>元素作为 <action> 子元素列举动作。当一个intent对象名仅仅是一个单独的动作,一个过滤器列举更多。这个列表不可以为空;管理器至少需要包含一个<action>元素,或它将阻止所有的intent。
传递一个intent给类别测试,每个intent里的类别需要匹配一个过滤器里的类别。过滤器列举附加的类别,但是它不可以忽略任何intent里的类别。
<data>元素的type属性指定数据的MIME类型。一般在过滤器里的情况比在URI里多。Itnent对象和过滤器可以使用*来表示子域——例如:text/*或audio/*——表示匹配任何子域。
<data>元素的type属性指定数据的MIME类型。一般在过滤器里的情况比在URI里多。Itnent对象和过滤器可以使用*来表示子域——例如:text/*或audio/*——表示匹配任何子域。
数据测试对比intent对象里的URI和数据类型和过滤器里的。规则如下:
a.仅仅当过滤器不指定任何URI或数据类型的时候,才会把一个没有包含URI或数据类型的intent对象传递给测试。
b.仅仅如它的URI匹配一个过滤器里的URI并且过滤器没有指定类型(这个类型不可以通过URI推断),会把一个包含URI不包含数据类型的intent传递给测试。这种情况仅出现于URI如mailto: 和tel:这样不引用实际数据的情况。
c.如果过滤器列出相同的数据类型并不指定URI,一个包含数据类型不包含URI的intent会传递给测试。
d.包含URI和数据类型的intent对象(或可以通过URI推断数据类型)如果它的类型和过滤器的类型的列表你的匹配,那么就测试数据类型部分。如果它的URI和过滤器列表的匹配,或包含content:、file:、没有指定URI,那么就测试URI部分。换句话说,组件可以断定如果过滤器列表仅仅有数据类型那么它支持content: 和 file:数据。
坚持不懈,总会进步!