http://blog.csdn.net/u012637501/article/details/41080891
为了比较深刻的理解并灵活使用Intent,我计划将这部分的学习分为两步:一是深入理解Intent基本概念以及其类;二是,通过实例来阐述如何灵活使用Intent来启动一个组件以及实现组件之间的传递数据。
一、什么是Intent,有什么作用?
Android的应用程序包括四大组件:Activity、contentProvider、Service、BroadcastReceiver,为了方便不同组件之间的交流通信,应用程序就采用了一种统一的方式启动组件及传递数据,即使用Intent。
Intent封装了Android应用程序需要启动某个组件的"意图",Intent类的对象是组件间的通信载体,一个Intent对象就是一组信息,其包含接收Intent组件所关心的信息(如action 和 Data)和Android 系统关心的信息(如Category等)。也就是说,发送"意图"的组件通过Intent对象所包含的内容,来启动指定的(即Component属性)或通过筛选(即Action&Category属性)的某(些)组件,然后实施相应的动作(即Action属性)并传递相应的数据(即Data属性)以便完成相应的动作。
二、Intent是如何实现组件间相互调用?
1.Intent实现
上图请求一个Activity组件的简单的实现流程图,算是用的最多的Intent解析实例。
首先,发出"意图"的组件,通过调用Context.startActivity(intent)开始启动组件:发出"意图"的组件传入已经构好的Intent对象(为一组信息,它决定了是否能够成功的启动另一个组件);
然后,调用"动作"实际的执行着Instrumentation对象,它是整个应用激活的Activity管理者,集中负责应用内所有Activity的运行。它有一个隐藏的方法execStartActivity方法,就是负责根据Intent启动Activity。该方法去掉一些细节,它做得最重要的事情,就是将此调用,通过RPC的方式,传递到ActivityManagerService。
最后,ActivityManagerService会将这些关键信息递交给另一个服务PackageManagerService,此服务掌握整个软件包及其各组件的信息,它会将传递过来的Intent,与已知的所有Intent Filters进行匹配(如果带有Component信息,就不用比了)。如果找到了,就把相关Component的信息通知回AcitivityManagerService,在这里,会完成启动Activity这个很多细节的事情。
2.Intent匹配
到底发出"意图"的组件是如何找到所需的组件呢?在这里,Intent Filters就开始起作用了,Intent Filters定义在AndroidMainFest.xml文件中,每一个Activity都会有一个<Intent Filters/>元素,它包含了<action/>、<data/>等子元素。当我们的intent对象没有包含Component信息时,这种"意图"被称之为隐形"意图"。也就是说,"意图"没有指明具体要启动哪个组件以及完成什么样的动作。这时我们就需要通过Intent Filters中的子元素进行信息匹配,从而确定当前包含Intent Filters属性的Activity是不是我们要启动的那个(些)组件。即发送"意图"组件配置好intent对象,被启动组件实现Intent Filters属性,最后,发送组件会根据被启动组件AndroidMainFest.xml中的<Intent Filters/>信息来确定它是不是目标组件。
三、Intent对象详解
Intent类的对象是组件间的通信载体,利用Intent对象我们可以很方便的实现不同组件之间的通信。一个Intent对象就是一组信息,这些信息都是通过其Component、Action、Category、Data、Extra和Flag这7种属性体现的。Intent代表了Android应用的启动"意图",Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,则取决于Intent的属性。
1.Action属性
Action属性为一个普通的字符串,它代表了该Intent对象要完成一个什么样的"动作"。当我们为Intent对象指明了一个action时,被启动的组件就会依照这个动作的指示表现出相应的行为,比如查看、拨打、编辑等,需要注意的是一个组件(如Activity)只能有一个action。我们可以方便自己的应用程序组件之间的通信,自定义action的(字符串)创建新的动作;也可以直接使用Intent类中的静态成员变量,比如ACTION_VIEW,ACTION_PICK,它们是Android中为action属性预定义的一批action变量。
在设置Intent对象Action属性时,有两种:
- (1)自定义字符串
- public final String CUSTOME_ACTION="intent.action.CUSTOME_JIANG";//字符串可以任意
- Intent intent=new Intent();
- intent.setAction(ActionAttr.CUSTOME_ACTION); //注意:ActionAttr为我们创建的类,也可以使用this.CUSTOME_ACTION
- (2)使用系统预定action常量
- Intent intent=new Intent();
- intent.setAction(Intent.ACTION_CALL); //其中ACTION_CALL为Intent类的静态成员变量,可以类直接调用
- //对应字符串"android.intent.action.CALL"
2.Data属性
Action属性为Intent对象描述了一个"动作",那么Data属性就为Intent对象的Action属性提供了操作的数据。这里需要注意的是,Data属性只接受一个Uri对象,一个Uri对象通常通过如下形式的字符串来表示:
Uri字符串格式:scheme://host:port/path 举例: content://com.android.contacts/contacts/1或tel://18819463209
在设置Intent对象Data属性时可以这样:
- Intent intent=new Intent();
- String data="content://com.android.contacts/contacts/1";
- Uri uri=Uri.parse(data);//将字符串转换为Uri
- intent.setData(uri);
- 或者
- Intent intent=new Intent();
- intent.setData(Uri.parse("content://com.android.contacts/contacts/1"));
博主笔记1:action属性和data属性为Intent所传递信息的主要部分,action/data属性举例:
ACTION_VIEW content://contacts/people/1 -- 传递的信息: 显示 号码为1的人相关信息
ACTION_DIAL content://contacts/people/1 -- 传递的信息:给编号为1的人 打 电话
ACTION_VIEW tel:123 -- 传递的信息:将号码123 显示
ACTION_DIAL tel:123 --传递的信息: 拨打 号码123
ACTION_EDIT content://contacts/people/1 -- 传递的信息: 编辑编号为1的联系人
ACTION_VIEW content://contacts/people/ -- 传递的信息:列出显示所有联系人.如果希望在查看某个联系人,需要定义一个新的intent并且属性设置为{ ACTION_VIEW content://contacts/N } 传递到一个新的Activity。
总结:action属性、data属性是intent的主要属性。
3.Catagory属性
通过Action,配合Data或Type属性可以准确的表达出一个完整的意图了。但为了使的"意图"更加精确,我们也给意图添加一些约束,这个约束由"意图"的Catagory属性实现。一个意图只能指定一个action属性,但是可以添加一个或多个Catagory属性。Category属性可以自定义字符串实现,但为了方便不同应用之间的通信还可以设置系统预定义的Category常量。调用方法addCategory 用来为Intent 添加一个Category,方法removeCategory 用来移除一个Category;getCategories方法返回已定义的Category。
在设置Intent对象Categoty属性时可以这样:
- (1)自定义字符串
- public final String CUSTOME_CATEGORY="intent.action.CUSTOME_CATEGORY";//字符串可以任意
- Intent intent=new Intent();
- intent.addCategory(ActionAttr.CUSTOME_CATEGORY);
- (2)使用系统预定action、category常量
- 以下代码实现当点击某个按钮时,通过Intent对象实现返回HOME桌面。
- Intent intent=new Intent();
- intent.setAction(Intent.ACTION_MAIN);
- intent.addCategory(Intent.CATEGORY_HOME);//返回Home桌面
博主笔记2:一般来说Action属性和Category属性都是同时使用的。在Android中,所有应用主Activity(就是单独启动时候,第一个运行的那个Activity...),都需要能够接受一个Category为 CATEGORY_LAUNCHER,Action为ACTION_Main的意图。对于发出"意图"的组件,我们可以通过setAction()、addCategory()方法为"意图"添加action属性或者同时添加Action、Category属性;对于接收"意图"的组件,在AndroidManifest.xm文件中,我们可以这样设置:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".ActionCateAttr"
android:label="第一个Activity界面" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> //默认Action
<category android:name="android.intent.category.LAUNCHER" /> //默认Category
</intent-filter>
</activity>
<activity
android:name=".SecondaryActivity"
android:label="第二个Activity界面" >
<intent-filter>
<action android:name="intent.action.JIANG_ACTION" />
<category android:name="intent.action.JIANG_CATEGORY" />
<category android:name="android.intent.category.DEFAULT" /> //默认Category
</intent-filter>
</activity>
注释:发出"意图"的Activity将Category为 CATEGORY_LAUNCHER,Action为ACTION_Main,接收"意图"的Activity须设置一个默认的Category属性CATEGORY_DEFAULT,这里不能将其设置为CATEGORY_LAUNCHER否者会报错。另外,如果我们使用了系统预定义的action常量,则需要在AndroidManifest.xm文件中添加相应的权限,这方面的内容我们将在第二部分讲到。
4.Type属性
Type属性用于指定该Data所指定Uri对应的MIME类型,这种类型可以是任何自定义的MIME类型,只要符合abc/xyz格式的字符串即可。这里需要注意的是,Type属性和Data属性一般会出现相互覆盖的情况,如果希望Intent既有Data属性也有Type属性,必须通过setDataAndType()方法来实现。对于Type属性的理解,我记得有篇博文是这样作比方的:说了Data,就必须要提Type,很多时候,会有人误解,觉着Data和Type的差别,就犹如泡妞和泡马子之间的差别一样,微乎其微。但其实不然,Type信息,是用MIME来表示的,比如text/plain,这样的东西。说到这里,两者差别就很清晰了,Data就是门牌号,指明了具体的位置,具体问题具体分析,而type,则是强调物以类聚,解决一批量的问题。实际的例子是这样的,比如,从某个应用拨打一个电话,会发起的是action为ACTION_DIAL且data为tel:xxx这样的Intent,对应的人类语言就是拨打xxx的电话,很具象。而如果使用type,就宽泛了许多,比如浏览器收到一个未知的MIME类型的数据(比如一个视频...),就会放出这样的Intent,求系统的其他应用来帮助,表达成自然语言应该就是:查看pdf类文档,这样的。
博主笔记3:MIME类型?
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML 文档,而为了支持多媒体数据类型,HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。MIME意为多功能Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
常见的MIME类型(通用型):
超文本标记语言文本 .html text/html
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
PDF文档 .pdf application/pdf
Microsoft Word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
任意的二进制数据 application/octet-stream
5.Ertras属性
通过上面的这些项,识别问题,基本完美解决了,剩下一个重要的问题,就是传参。Extras是用来做这个事情的,它是一个Bundle 类的对象,有一组可序列化的key/value对组成。每一个Action都会有与之对应的key和value类型约定,发起Intent的时候,需要按照要求把Data不能表示的额外参数放入Extras中。
6.Flags属性
能识别,有输入,整个Intent基本就完整了,但还有一些附件的指令,需要放在Flags中带过去。顾名思义,Flags是一个整形数,有一些列的标志 位构成,这些标志,是用来指明运行模式的。比如,你期望这个意图的执行者,和你运行在两个完全不同的任务中(或说进程也无妨吧...),就需要设置FLAG_ACTIVITY_NEW_TASK 的标志位。
7.Component属性
通常来说,"意图"可分为显示intent和隐式intent。Intent Filters它是用来描述一个Activity或 Serveice等组件,我们通过在组件AndroidManifest.xml中<intent-ilters/>元素中添加<action/>等属性,以满足期望能够响应怎么样的Intent,这种没有指明要启动组件名方式就称之为隐式intent。当然,我们也可以使"意图"实现启动指定的组件,即称之为显示intent,主要通过Component属性来实现。Intent的Component属性需要接受一个ComponentName对象,这个对实现将要启动指定组件的类名、类所在的包名绑定在intent上。
- ComponentName comp=new ComponentName(ComponentAttr.this,SecondaryActivity.class);
- Intent intent=new Intent();
- intent.setComponent( comp);//设置intent的Component属性,指定"意图"要启动组件的包和类名
- 注释:第一句用于创建一个ComponentName对象,来指定包名和类型-这就可以唯一地确定一个组件类。
四、Intent相关类
1.Activity类
这里我们只需学习使用Intent启动Activity组件将要用的的方法
void |
startActivity(Intent intent)
作用:启动Activity,具体启动哪个Activity和怎么样启动由intent属性决定
|
void |
startActivityForResult(Intent intent, int requestCode)
作用:启动Activity,并返回一个结果。当被启动的Activity退出时,会调用 onActivityResult() 方法并向其传入一个 requestCode参数,这个 requestCode参数为非负数(>0),作用是标志是哪个Activity组件发出的"意图",需要注意的是如果 requestCode小于0时,这个方法的只能用于启动一个Activity而不能返回值了。另外,Intent的action属性设为能够返回一个结果,如果设置为 Intent.ACTION_MAIN or Intent.ACTION_VIEW,也是不能获取结果的。
|
待写:另外还有如何启动Service、BroadcastReceiver组件的方法,这以后学到了再说吧。
2.Intent类
(1)构造函数
|
|
|
|
|
|
|
|
|
为一个指定的组件创建一个带action和data属性的意图
|
- Android笔记一.深入理解Intent和IntentFilters(一)
深入理解Intent和IntentFiler(一) 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 为了比較深刻的理解并灵活使用Inten ...
- Pro Android 4 第五章 理解Intent
Android引入了一个名为Intent的概念用来唤醒各种组件.Android中的组件包括:activities(UI 组件),services(后台代码),broadcast receiv ...
- Android两个注意事项.深入了解Intent和IntentFilter(两)
深入理解Intent和IntentFiler(二) 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 在上一篇文章中,我们比較具体学习了&q ...
- [译]:Xamarin.Android开发入门——Hello,Android Multiscreen深入理解
原文链接:Hello, Android Multiscreen_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android Multiscreen深入理解. 本 ...
- Android中Intent传值与Bundle传值的区别详解
Android中Intent传值与Bundle传值的区别详解 举个例子我现在要从A界面跳转到B界面或者C界面 这样的话 我就需要写2个Intent如果你还要涉及的传值的话 你的Intent就要写两 ...
- android intent隐式调用之一个应用程序启动另一个应用程序
理解Intent的关键之一是理解清楚Intent的两种基本用法:一种是显式的Intent,即在构造Intent对象时就指定接收者,这种方式与普通的函数调用类似:另一种是隐式的Intent,即Inten ...
- Android开发-API指南-Intent和Intent过滤器
Intents and Intent Filters 英文原文:http://developer.android.com/guide/components/intents-filters.html 采 ...
- Bundle、Intent、SharedPreferences
Intent与Bundle的共同点:都继承Parcelable Intent传值与Bundle传值的区别 eg:我现在要从A界面 跳转到B界面或者C界面 这样的话 我就需要写2个Intent ...
- 最全面的Android Intent机制讲解
对于大型软件开发经验较少的程序员来说,这可能是一个不太容易理解的抽象概念,因为它与我们平常使用的简单函数调用,或者通过库调用接口的方式不太一样.在 Intent 的使用中你看不到直接的函数调用,相对函 ...
随机推荐
- Java设计模式学习记录-组合模式
前言 今天要介绍的设计模式是组合模式,组合模式也是结构型设计模式的一种,它主要体现了整体与部分的关系,其典型的应用就是树形结构.组合是一组对象,其中的对象可能包含一个其他对象,也可能包含一组其他对象. ...
- [JZOJ5970] Space
Description 在一个四维空间中,给 \(4\) 个 \(n\) 的排列 \(A,B,C,D\),对于点 \((x,y,z,w)\) ,到点 \((A_x,B_y,C_z,D_w)\) 的花费 ...
- [POJ 2689] Prime Distance
Description 给定两个整数 \(L,R\;(1\leq L\leq R\leq 2^{31},R-L\leq 10^6)\) ,求闭区间 \([L,R]\) 中相邻两个数最大的差是多少,输出 ...
- c语言中阶乘的精确值
对于大数的操作,可能超出int,甚至long的表示范围,对此,可以使用数组来存储大数,下列代码为求1000以内数的阶乘的代码,代码如下: #include <stdio.h> #inclu ...
- Extjs 项目中常用的小技巧,也许你用得着(2)
接着来,也是刚刚遇到的 panel怎么进行收缩 collapsible: true, 这会panel就会出现这个 点这个就可以收缩了 panel怎么随便拉伸,也就是让那个小黑三角出现 split: t ...
- MVC和WebForm区别
WebForm的理解 1. WebForm概念 ASP.NETWebform提供了一个类似于Winform的事件响应GUI模型(event-drivenGUI),隐藏了HTTP.HTML.JavaSc ...
- MEF 插件式开发之 小试牛刀
MEF 简介 Managed Extensibility Framework 即 MEF 是用于创建轻量.可扩展应用程序的库. 它让应用程序开发人员得以发现和使用扩展且无需配置. 它还让扩展开发人员得 ...
- HTML暗黑料理之a标签执行请求不跳转页面
不是被逼无奈不建议用这HTML暗黑料理. <iframe id="></iframe> <a class="large green button&qu ...
- js-QuickStart-base.js
// 1.变量(Variables) var myVariable; myVariable = 'Bob'; // 数据类型 string number boolean array object // ...
- lfs(systemd版本)学习笔记-第1页
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 一名linux爱好者,记录构建Linux From Scratch的过程 经博客园-骏马金龙前辈介绍,开始接触学习lfs,用博客 ...