Intent就是一个激活组件的消息对象,用于组件之间的通讯。须要注意的是,能被Intent激活通讯的组件只有三类:Activity、Service和BroadcastReceiver。对应这三类组件,
Intent
有下面三种使用场景:html
Intent
为参数调用startActivity()启动一个Activity实例。这个Intent告诉Activity去启动,而且传递了一些必要数据给它。在Activity结束时,若是想要从这个结束的Activity接收数据,可使用startActivityForResult()启动,这样在你的Activity的 onActivityResult()
回调就会接收到单独的结果Intent。
Intent
为参数调用startService()
启动一个Activity实例。这个Intent告诉Service去启动,而且传递了一些必要数据给它。若是Service被设计成C/S结构的Server,你能够在其它组件中以Intent为参数调用bindService()绑定这个Service。
sendBroadcast()
, sendOrderedBroadcast()
, or sendStickyBroadcast()
)。上述这些Intent传递,不会有重叠。广播Intent仅被传递给Receiver,永远不会给Activity或者Service;一个传送给Activity的Intent是只会被传递给Activity,永远不会给一个Service或Receiver;如此类推。java
Intent有两种类型:android
显式Intent启动,Android系统能够经过这个Intent对象当即启动组件。web
隐式Intent启动,Android系统会将Intent的内容与设备全部app的manifest文件中的Intent过滤器比较,找出最合适的组件去启动。若是Intent和Intent过滤器匹配,系统就会启动组件而且传递Intent对象。若是有多个Intent过滤器匹配,系统会显示一个对话框,供用户选择使用哪个app。(注,Intetn过滤器是manifest中的一个符号,指明一个组件能够接收什么样的Intent。)浏览器
上图为隐式Intent启动Activity的过程。【1】Activity A经过action建立一个Intent,让后以这个Intent为参数调用startActivity()。【2】Android系统会隐式Intent,搜索匹配全部app的Intent过滤。【3】系统匹配到Activity B,调用它的onCreate()方法而且传递Intent。安全
警告:为了确保app的安全性,一般使用显式Intent启动Service,而且不给Service声明Intetn过滤器。使用隐式Intent启动Service是危险的,由于你不可能肯定多少个Service会响应这个Intetn,而且用户看不到哪一个Service启动了。网络
Intent的主要信息以下:app
启动的组件名称。框架
对于隐式启动来讲,Component name是可选的。可是对于显示启动来讲,Component name是必须的信息。没有Component name信息的Intent就是一个隐式的Intent,系统会基于Intent的其它信息(好比action、data、category)决定哪一个组件来接收Intent。ide
执行通用操做的字符串。
系统框架提供了许多action常量,下标列出部份内容:
常量 | 目标组件 | Action |
ACTION_CALL | Activity | 打电话 |
ACTION_SCREEN_ON | BroadcastReceiver | 屏幕开启 |
ACTION_TIMEZONE_CHANGED | BroadcastReceiver | 时区变化 |
自定义action,应该尽可能使用包名做为前缀。好比:
1 static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
被执行数据的URI和它的MIME类型。一般,不一样的action会伴随不一样的数据类型。例如, 若是action为ACTION_EDIT, 那么Data将包含待编辑的数据URI. 若是action为ACTION_CALL, Data将为tel:电话号码的URI. 若是action为ACTION_VIEW, 则Data为http:网络地址的URI.
当建立一个Intent时,为数据指定一个MIME类型做为URI的补充,是很是必要的。好比,一个activity能够显示图片可是不能播放音频(尽管图片和音频的URI是很是类似的)。所以,为数据指定一个MIME类型能够帮助Android系统找到最佳的组件接收Intent。
然而,MIME类型有时候能够经过特别的URI推测出来。好比content:
URI,它代表数据位于设备上面,而且数据是被ContentProvider控制的,这就使的数据的MIME类型对系统来讲是可见的。
警告:若是想要设置URI和MIME类型,应该调用setDataAndType()
;而不是同时调用setData()和setType(),由于它们会使彼此的值无效。
一个附加信息的的字符串,包含了关于能够处理该Intent的组件种类信息。一个Intent能够有多个Category,可是大多数Intent须要Category。下面是一些公共Category信息:
常量 | 含义 |
CATEGORY_BROWSABLE | 目标activity能够被浏览器安全的启动,用来显示连接应用的数据——好比,一张图片或者一封邮件 |
CATEGORY_GADGET | 这个activity能够被嵌入到另外一个activity中 |
CATEGORY_HOME | 这个activity电视home界面,即设备打开或者按Home键看到的第一个页面 |
CATEGORY_LAUNCHER | 这个activity能够做为task的初始activity,而且是被列应用程序启动器中 |
CATEGORY_PREFERENCE | 目标activity是一个选项面板 |
上面的内容(component name, action, data, and category)描述了Intent的典型特征。经过读取这些内容,Android系统能够决定哪一个组件能够被启动。
然而,Intent还能够携带一些额外信息,这些额外信息不会影响系统选取组件,这些额外信息就是Extras和Flags。
Key-value形式的额外信息。
Intent类定义了许多的EXTRA_*
常量的标准数据类型。若是要自定义extra keys,应该尽可能使用包名做为前缀:
1 static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
flag被定义在Intent类中,它做为Intent的metadata(描述数据的数据)。flag能够告诉Android系统如何启动一个activity(好比,这个activity属于哪个task),而且在启动后如何管理这个activity(好比,这个activity是否属于recent activities列表)。
PendingIntent是对Intent的包装。PendingIntent的主要目的是授予外部程序使用被包装的Intent,好像Intent在本身的进程中执行。
pending intent的主要使用场景以下:
NotificationManager会执行这个Intent)。
因为Intent被设计成只有特定类型的组件(Activity、Service和BroadcastReceiver)才能处理,所以PendingIntent的建立也必需要基于这层考虑。建立PendingIntent时,必须根据组件类型的不一样,分别调用对应的方法建立:
PendingIntent.getActivity()
for an Intent
that starts an Activity
.PendingIntent.getService()
for an Intent
that starts a Service
.PendingIntent.getBroadcast()
for a Intent
that starts an BroadcastReceiver
.这些方法最好使用当前app的Context。更多的关于PendingIntent的使用,参考Notifications和App Widgets的Api指南。
当系统收到一个隐式Intent的时候,系统会经过比较Intent和Intent比较器寻找最佳的activity,系统基于如下三个方面来比较:
一个Intent过滤器能够声明零个或多个<action>
元素。好比:
1 <intent-filter> 2 <action android:name="android.intent.action.EDIT" /> 3 <action android:name="android.intent.action.VIEW" /> 4 ... 5 </intent-filter>