1. 说明
Android中提供了Intent机制来协助应用间或者应用程序内部的交互与通讯。
Intent的两种基本用法:一种是显式的Intent,即在构造Intent对象时就指定接收者,这种方式与普通的函数调用类似;另一种是隐式的Intent,即Intent的发送者在构造Intent对象时,并不知道接收者是谁,只是指出接收者的一些特性(比如说启动音乐播放软件)
2. 使用方法
1) 启动服务
a) 关键函数
context.startService()或context.bindService()
b) 示例
Intent i = new Intent(this, MyTestService.class);
this.startService(i); // 启动service
2) 发送广播
a) 关键函数
context.sendBroadcast()
b) 发送方
String msg = “test”;
Intent i = new Intent(“com.test.bc”);
i.pubExtra(“msg”, msg);
this.sendBroadcase(i);
c) 接收方
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
registerReceiver(mReceiver.interFilter);
3) 启动应用程序
a) 关键函数
context.startActivity()
b) 示例
Intent intent =
new Intent(“com.android.browser“, “com.android.browser.BrowserActivity“);
startActivity(intent);
3. Intent的组成
Intent的参数可多可少,系统根据不同的参数组合过滤出一个或多个适合规则的界面
1) 调用方:以下几个规则可以同时指定,也可以指定一部分或几部分
Component:指定包名类名来调用(见上例),它是晚绑定,不会在编译时报错
Action:指定做什么的规则(比如ACTION_DIAL指定拨号类型应用),以供过滤
Data:提供的重要数据,通常是Uri,同时也提供数据的类型,以供过滤
Type:用于指定类型,以供过滤(比如ACTION_VIEW同时指定为Type为Image,则调出浏览图片的应用)
Category:指定范围
Extras:通过Bundle类传参, 数据多,数据量大时用它传
Flags:标志位(比如FLAG_ACTIVITY_NEW_TASK指定新开一个任务)
2) 被调用方
在AndroidManifest.xml中的<intent-filter>中声明规则
例如: 一般程序都需要在inter-filter中加入android.intent.category.LAUNCHER的声明, 以便被程序启动器(Launcher)识别, 即以点击图标的方式供用户运行
3) 示例
Intent intent = new Intent();
intent.setClassName(“com.android.browser“,
“com.android.browser.BrowserActivity“); // 打开浏览器
Uri data = Uri.parse(“http://www.google.com“);
intent.setData(data); // 打开某网页
intent.addFlag(Intent.FLAG_ACTIVITY_NEW_TASK); // 以新建任务方式打开
intent.setAction(Intent.ACTION_VIEW); // 以浏览方式打开
startActivity(intent);
4. Intent的源码实现
1) Intent解析,过滤规则对应出具体应用
frameworks/base/core/java/android/content/IntentFilter.java
2) Intent定义,规定程序中的使用的Define与xml中字串的对应关系
frameworks/base/core/java/android/content/Intent.java
5. 参考
Intent构成
Intent被译作意图,其实还是很能传神的,Intent期望做到的,就是把实现者和调用者完全解耦,调用者专心将以意图描述清晰,发送出去,就可以梦想成真,达到目的。
- Action 。当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想做 三个俯卧撑;我要看 一部x片;我要写 一部血泪史,之类云云。在Intent中,Action就是描述看、做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK ,之类的,基本涵盖了常用动作,整一个降龙十八掌全集。当然,你也可以与时俱进,创造新的动作,比如lou这样的。与系统预定义的相比,这些自定义动作的流通范围很是有限,除非做了非常NB的应用,大家都需要follow你,否则通常都是应用内部流通。
- Data 。当然,光有动作还是不够的,还需要有更确切的对象信息。比如,同样是泡 这个动作,但泡咖啡 ,和泡妞 ,就差之千里了。Data的描述,在Android中,表现成为一个URI 。用在内部通信中,可能描述是Content Provider用的形如content://xxxx 这样的东东,抑或是外部的一个形如tel://xxxx 这样的链接。总而言之,是能够清楚准确的描述一个数据地址的uri。
- Type 。说了 Data,就必须要提Type,很多时候,会有人误解,觉着Data和Type的差别,就犹如泡妞 和泡马子 之间的差别一样,微乎其微。但其实不然,Type信息,是用MIME 来表示的,比如text/plain , 这样的东西。说到这里,两者差别就很清晰了,Data就是门牌号,指明了具体的位置,具体问题具体分析,而type,则是强调物以类聚,解决一批量的问 题。实际的例子是这样的,比如,从某个应用拨打一个电话,会发起的是action为ACTION_DIAL且data为tel:xxx这样的 Intent,对应的人类语言就是拨打xxx的电话 ,很具象。而如果使用type,就宽泛了许多,比如浏览器收到一个未知的MIME类型的数据(比如一个视频...),就会放出这样的Intent,求系统的其他应用来帮助,表达成自然语言应该就是:查看 pdf类文档 ,这样的。
- Category 。通过Action,配合Data或Type,很多时候可以准确的表达出一个完整的意图了,但也会有些时候,还需要加一些约束在里面才能够更精准。比如,如果你虽然很喜欢做俯卧撑,但一次做三个还只是在特殊的时候才会发生,那么你可能表达说:每次吃撑了的时候 , 我都想做三个俯卧撑。吃撑了,这就对应着Intent的Category的范畴,它给所发生的意图附加一个约束。在Android中,一个实例是,所有应 用主Activity(就是单独启动时候,第一个运行的那个Activity...),都需要能够接受一个Category为 CATEGORY_LAUNCHER,Action为ACTION_Main的意图。
- Component 。在此之前,我们企图用Action,Data/Type,Category去描述一个意图,这是Android推荐,并期望大家在大多数时候使用的,这样模式在Android中称做Implicit Intents , 通过这种模式,提供一种灵活可扩展的模式,给用户和第三方应用一个选择权。比如,还是一个邮箱软件,他大部分功能都好,就是选择图片的功能做的很土,怎么 办?如果它采用的是Implicit Intents,那么它就是一个开放的体系了,手机中没有其他图片选择程序的话,可以继续使用邮箱默认的,如果有,你可以任意选择来替代原有模块完整这功 能,一切都自然而然。但这种模式,也不是没有成本,需要付出的是一些性能上的开销,因为毕竟有一个检索过程。于是,Android提供了另一种模式,叫做Explicit Intents ,就需要Component的帮助了。Component就是类名 ,完整的,形如com.xxxxx.xxxx ,一旦指明了,一切都清晰了,找的到这个类(当然会是一个特定的子类...),成功,反之,失败。这个好处,自然是速度,适合在你明确知道这就是一个内部模块的时候,使用它。
- Extras 。通过上面的这些项,识别问题,基本完美解决了,剩下一个重要的问题,就是传参。Extras是用来做这个事情的,它是一个Bundle 类的对象,有一组可序列化的key/value对 组成。每一个Action,都会有与之对应的key和value类型约定,发起Intent的时候,需要按照要求把Data不能表示的额外参数放入Extras中(当然,如果不需要额外附加参数,就算了...),否则执行者拿到的时候会抓狂的。
- Flags 。 能识别,有输入,整个Intent基本就完整了,但还有一些附件的指令,需要放在Flags中带过去。顾名思义,Flags是一个整形数,有一些列的标志 位构成,这些标志,是用来指明运行模式的。比如,你期望这个意图的执行者,和你运行在两个完全不同的任务中(或说进程也无妨吧...),就需要设置FLAG_ACTIVITY_NEW_TASK 的标志位。
Intent匹配
如上图所示,要想跑通整个流程,另一个很重要的东西,就是Intent Filters , 它是用来描述一个Activity或 Serveice等组件,期望能够响应怎么样的Intent。如果一个组件,只希望别的组件通过Explicit Intents(就是指明Component...)的方式来找到它,那么就不需要添加Intent Filters,反之,一定需要一个或若干个Intent Filters。Intent Filter的各个项,犹如Intent照镜子过来的效果,包括Action,Catagory,Data,Type等。
Intent实现
上图,是请求一个Activity组件的简单实现流程图,算是用的最多的 Intent解析实例。流程从调用Context.startActivity(Intent) 开始,调用者传入构造好的Intent对象,然后流程会让实际的执行者,是Instrumentation 对象来完成。它是整个应用激活的 Activity管理者,集中负责该应用内所有Activity的起承转合生离死别。它有一个隐藏的方法execStartActivit y 方法,就是负责根据Intent启动Activity的。去掉一些细节,它做得最重要的事情,就是将此调用,通过RPC的方式,传递到ActivityManagerService 。
前面一直再说,系统核心层 ,其实这里所谓的系统核心层,就是负责Android一些关键事务的一组服务 。它们同样运行在虚拟机上,和普通的Service实现机理是一致的,只不过它们不抛头露脸只是默默的在下层服务,故谓之核心嘛。 AcitivityManagerService,是负责Activity调度的服务,也许日后提及调度细节的时候还会有涉及。
原文地址:http://blog.csdn.net/liuyahui312031/article/details/6044887