from : http://blog.csdn.net/biexf/
靳岩 姚尚朗 《Google android 开发入门与实战》读书笔记Intent完整篇
关于Intent:
1)Intent基础:
Intent可以说是android的灵魂,程序跳转和传递数据的时候基本要靠Intent,在android的官方API里面对Intent的定义如下:An Intent is an abstract description of an operation to be performed. 是对一次将要执行操作的抽象描述,具体有三种形式:
.通过startActivity方法来启动一个新的Activity;
.通过broadcast Intent机制可以将一个Intent发送给任何对这个Intent感兴趣的BroadcastReceiver;
.通过startService(Intent)或者bindService(Intent,ServiceConnection,int)来和后台的Service进行交互;
2)用Intent来启动一个新的Activity:
Intent最常用的用途是连接一个应用的各个Activity,如果我们把Activity比作积木的话,Intent好比胶水;Intent中或者指定一个Activity,或者里面只是包含了选定activity的信息,但是具体启动哪个activity是由系统去决定的,android的系统负责挑选一个最满足匹配挑选条件的Activity;
2.1)启动一个特定的Activity:
--------------------------------------------------------------------------------------------------------------------
Intent intent = new Intent(CurrentActivity.this,OtherActivity.class);
startActivity(intent);
--------------------------------------------------------------------------------------------------------------------
当执行了如上的方法时,android系统新创建OtherActivity的对象,并将其移动到整个Activity堆栈的顶部.
2.2)启动一个未指明的Activity:
--------------------------------------------------------------------------------------------------------------------
Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse(“tel:115-1345”));
startActivity(intent);
--------------------------------------------------------------------------------------------------------------------
上述代码我们并没有指定哪个Activity去执行,只是把我们对启动Activity的描述信息放在Intent当中。那么当执行startActivity方法后,android系统就会去寻找,到底哪个Activity最合适。最后会根据描述信息找到处理电话的Activity,然后启动,执行;这样做的好处:对于第三方的Activity,它只需要描述自己在什么情况下会被执行,如果我们启动Activity的描述信息正好和第三方的Activity的描述信息相匹配,那么这个第三方的Activity就会被启动;
2.3)启动一个Activity的返回值:
startActivity的方法启动了Activity之后,这种方法启动的Activity执行完毕之后,不会返回数据给前一个Activity。startActivityForResult方法用于启动一个Activity并且新的Activity执行完毕之后需要返回到启动它的Activity来执行回调函数;
eg:
step1:
--------------------------------------------------------------------------------------------------------------------
@Override
public void onCreate(Boudle savedInstanceState){
super.onCreate(savedInstanceState);
l1 = new OnClickListener(){
public void onClick(View){
Intent intent = ..;
intent.putExtra(“activityMain”,”数据来自activityMain”);
startActivityForResult(intent,REQUEST_CODE);
}
}
}
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
….
}
--------------------------------------------------------------------------------------------------------------------
step2:对Activity1:
--------------------------------------------------------------------------------------------------------------------
public void onCreate(Boudle savedInstanceState){
super.onCreate(savedInstanceState);
l1 = new OnClickListener(){
public void onClick(View){
Bundle bundle = new Bundle();
bundle.putString(“store”,”数据来自Activity1”);
mIntent.putExtras(bundle);
setResult(RESULT_OK,mIntent);
finish();
}
}
}
--------------------------------------------------------------------------------------------------------------------
其中 setResult(RESULT_OK,mIntent)中这行代码设置了Activity1执行结束时候的返回值;所有的返回值都是放置在一个intent中,并且通过intent进行传递;执行完finish()之后,Activity1执行结束,并且将返回值返回给调用它的父Activity;
关于requestCode,resultCode等:
在startActivityForResult(Intent intent,int requestCode)中:
第一个参数包含启动Activity的信息;
第二个参数是一个整数(请求码),会在onActivityResult方法里面被返回,可以据此通过不同的请求码去启动一个Activity,在onActivityResult中通过不同的请求码来区分不同的启动,从而做不同的处理;
在onActivityResult(int requestCode,int resultCode,Intent data)中:
第一个参数是启动新Activity时候的请求码,即startActivityForResult中requestCode;
第二个参数是结果码,在新启动的子Activity里通过setResult(int resultCode,Intent data)方法中设置。通过不同的结果码,我们可以了解子Activity中操作结果的一些信息,比如结果码最经常的有2个:一个是RESULT_OK,代表子Activity的操作成功,还有一个RESULT_CANCELED,表示子Activit里面的操作取消了,没有成功;
3)Intent详解:
关于Intent对操作的抽象描述包括的部分:
.对执行动作的描述:操作(Action);
.对于这次动作相关联的数据进行描述:数据(data);
.对数据类型的描述:数据类型(type);
.对执行动作的附加信息进行描述:类别(Category);
.对其它一切附加信息的描述:附件信息(extras);
.对目标组件的描述:目标组件(component);
3.1) android系统自带的Action的介绍:
android中常用的标准动作:
.ACTION_MAIN : 在每个androidManifest.xml文档中可以看到的值:”android.intent.action.MAIN”;它标记当前Activity作为程序的一个入口;
.ACTION_VIEW:将数据显示给用户.ACTION_VIEW通常和特定的data相配合使用,用于给用户显示数据;
.ACTION_DIAL:用于描述给用户打电话的动作,通过和data配合使用将会触发给特定data的用户打电话;
.ACTION_PICK:从特定的一组数据中进行数据操作;
.ACTION_DELETE:删除特定的数据;
.ACTION_EDIT:编辑特定的数据;
android中与动作(ACTION)相关的数据(data)的介绍:
android中采用指向数据的一个URI来表示data,例如,在联系人应用中,一个指向某联系人的URI可能为:content://contracts/1。
这种URI表示,通过ContentURI来描述,(android.net.ContentURI类);以联系人应用为例,以下是一些action/data对,及要表示的意图:
.VIEW_ACTION content://contracts/1 显示标识符”1”的联系人的详细信息;
.EDIT_ACTION content://contracts/1 编辑标识符为”1”的联系人的详细信息;
.VIEW_ACTION content://contracts/ 显示所有联系人的列表;
.PICK_ACTION content://contracts/ 显示所有联系人的列表,并且允许用户在列表中选择一个联系人,然后把这个联系人返给父Activity;(电子邮件客户端可以使用这个Intent,要求用户在联系人列表中选择一个联系人);
3.3)Intent中其他属性:
ACTION大多数情况下只包含上面介绍的Action和Data属性,但是有时候也包含下面的属性:
.类别(category),执行动作的附加信息,eg:LAUNCHER_CATEGORY表示Intent的接受者应该在Launcher中作为顶级应用出现;而ALTERNATIVE_CATEGORY表示当前的Intent是一系列可选动作的一个;
.数据类型(type),显式指定Intent的数据类型(MIME),一般的Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导;
.组件(component):指定Intent目标组件的类名称,通常intent会根据其他属性信息,如action,data/type,category进行查找,最终找到一个与之匹配的目标组件。但是,如果直接指定component的话,将直接使用它指定的组件,而不再执行上述查找过程;指定了这个属性,则Intent的其它所有属性都是可选的;
.附加信息(extras):是其他所有附加信息的集合。使用extras可以作为组件提供扩展信息,例如:如果要执行”发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件;
总之:action, data/type,category 和 extras一起组成了一种级别的语言规范,这种语言使系统能够理解诸如”查看某联系人的详细信息”或者”给某一打电话”之类的短语。随着应用不断增加到系统中,android系统可以添加新的action,data/type,category来扩展这种语言;
4.Android解析Intent的实现:
应用中有两种形式来使用Intent.
.直接使用Intent:指定了component属性的Intent(setComponent(cName) 或者setClass(Content,class))。通过直接指定具体的组件类,通知应用启动相应的组件;
这种使用方式不需要解析;
.间接使用Intent:没有指定component属性的Intent。这些Intent需要包含足够的信息,这样系统才能根据这些信息,在所有可用的组件中,确定满足条件的Intent组件;
这种使用方式android需要对Intent中的指定信息进行解析;通过解析,将Intent映射给可以办理此Intent的Activity、Receiver或者Service。Intent解析机制主要是通过查找已注册在AndroidManifest.xml中所有IntentFilter以及其中定义的Intent,最终找到匹配的Intent;
解析过程中,Android通过Intent的action、type、category这3个属性来进行判断,判定方法:
a)如果Intent指明了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不匹配;
b)如果没有提供type,从data中得到数据类型。和action一样,目标组件中的数据类型列表中必须包含Intent的数据类型,否则不能匹配;
c)如果Intent中的数据不是具体内容而是URI形式的话,则将根据Intent中数据的Schema(如http: 或者mailto:)进行匹配。同上,Intent的shema必须出现在目标组件的schema列表中;
d)如果Intent指定了一个或者多个category,这些类别必须全部出现在组件的类别列表中。例如如果Intent中包含了两个类别:LAUNCHAR_CATEGORY和ALTERNATIVE_CATEGORY,解析的目标组件必须至少包含这两个类别;
举例:
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
代码解释:
上面例子中,第一个Activity是ActivityMain,是应用的入口,动作(action)为”android.intent.action.MAIN”,ActivityMain为这个应用中的第一个Activity,类别(category)为”android.intent.category.LAUNCHER”表示当程序启动时,ActivityMain会被放在启动Activity堆栈的顶层;
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
代码解释:
action: android.intent.action.View表示动作时View动作,
category=”android.intent.category.default”Category为缺省类型;
category=” android:intent.category.BROWSEABLE”,表示ActivityAuthSuccess可以通过浏览器进行启动,同时定义了数据类型的匹配模式为schema=”haiyang”,也即当链接为”haiyang://”模式的时候可以触发ActivityAuthSuccess这个Activity来进行处理;