android 自学日记(三) ---Intent
什么是Intent?
android中四分之三的组件类型(activitie、service和 broadcast receiver)都是 通过intent激活的。 Intent把不同的独立的组件在运行期绑定在一起(可以把它们当作从其它组件中请求动作的消息), 无论这些组件是同一个应用内的或者其它应用的组件都可以。所以说Intent是一个桥梁,连接android各组件。
显示Intent:
使用Intent是需要先创建一个Intent的对象:
Intent intent = new Intent();
Intent提供了几种构造器,都是用于指定目标组件;
显示Intent,顾名思义就是显示地指定intent要连接的目标:
Intent intent = new Intent(Context packageContext, Class<?> cls);
第一个参数Context就是上下文,即告诉程序在哪里启动。
PS:Context是一个抽象基类,我们可以通过它访问当前包的资源(getResources、getAssets)和启动其他组件(Activity、Service、Broadcast)以及得到各种服务(getSystemService)。
Context提供了一个应用的运行环境,在Context的大环境里,应用才可以访问资源,才能完成和其他组件、服务的交互,Context定义了一套基本的功能接口,可以理解为一套规范,而Activity和Service是实现这套规范的子类。
第二个参数是目标类,即想要启动哪个类(可以是Activity、Service或者BroadcastReceiver)。
Intent只是一个“意图”,因此还需要配合具体的方法来实现这个意图:
组件 | 启动方式 |
---|---|
Activity | startActivity(Intent intent) |
startActivityForResult(Intent intent,int requestCode) | |
Service | startService(Intent service) |
bindService(Intent service, …) | |
BroadcastReceiver | sendBroadcast(Intent service) |
sendBroadcast(Intent intent, String receiverPermission) | |
sendOrderdBroadcast(Intent intent, …) | |
sendStickyBroadcast(Intent intent) | |
sendStickyOrderBroadcast(Intent intent, …) |
隐式Intent:
隐式Intent即未明确地指定想要启动的组件,只是指定了满足的条件,任何满足条件的组件都能被启动。
Intent intent = new Intent(String action);
这个构造器里的action就是指定的条件(还有其他属性可以指定条件,见下文),可以是任意的一个字符串,但一般会使用“包名.intent.action.指定的常量” 来作为指定条件。
有了条件,那如何知道组件是否满足该条件那?
只需要在AndroidManifest.xml配置文件注册组件时在intent-filter属性中注明就可以了:
<intent-filter> <action android:name="String action"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter>
隐式Intent还可以启动其他程序内组件,例如:
Intent intent = new Intent(intent.ACTION_VIEW, Uri.parse("http://www.baidu.com")); startActivity(intent);
此处就是可以在Activity打开一个网页,并且访问的是”http://www.baidu.com“。
传递数据:
Intent还可以传递数据,只需要将数据放入intent中就可以了,intent提供了一系列放入数据的方法:
intent.putExtras(Bundle extras);//放入Bundle类的数据intent.putExtra(String key,Type value);//放入键值对形式的数据intent.putSerializable(String key, Serializable value)//放入可序列化的对象
取出的话同样很方便,也有对应的方法:
getIntent().getExtras();getIntent().getStringExtra(String key);getIntent().getSerializableExtra(String key);
其中的String可以变成其他基础类型的数据,如int、char等.
Intent属性:
Intent有7种属性,分别是:Component(组件名)、Action(动作)、Category(类型)、Data(数据)、Type(类型)、Extra(扩展)和 Flag(标志)。
Component(组件名)
就是上文显示Intent提到的指定目标组件,可以在intent构造器中直接指定,同样也可以用其他方法指定:
Component属性需要接受一个ComponentName对象,可以通过如下构造器创建:
ComponentName(String package, String class);ComponentName(Context package, String class);ComponentName(Context package, Class<?> cls);
这三种构造器本质是一样的,就是需要指定包名和类名,然后调用intent的setComponent()方法就完成了指定组件;
不用这个构造器,intent还可以直接调用如下方法设置Component属性:
setClass(Context package, Class<?> cls);setClassName(Context package, String className);setClassName(String packageName, String className);
Action(动作)、Category(类型)
这两个属性可以一起看,Action表示该intent所要完成的抽象的“动作”,而Category则是额外的附加类别信息。
上文隐式Intent其实就是用到了这两个属性,这两个属性结合起来就构成了隐式intent的条件。
除了上文提到的构造器中指定,还可以用intent的方法指定:
intent.setAction(String action); intent.addCategory(String category);
同样地,要想满足Action和Category属性就需要在intent-filter元素中添加对应的内容:
<intent-filter> <action android:name="String action"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter>
intent-filter元素中可以包含:
1~N 个action子元素;
(当包含多个action时,只要满足一个action就可以启动该组件;
intent-filter元素至少应该包含一个action,否则任何Intent请求都不能和该intent-filter匹配。)
1~N个category子元素;
(默认有一个category子元素,有aciton元素就要显示写出;
没有的话无法响应满足aciton的隐式intent启动)
0~1个data子元素;
常用的aciton常量
Acntion常量 | 对应字符串 | 说明 |
---|---|---|
ACTION_VIEW | android.intent.action.VIEW | 查看指定数据 |
ACTION_EDIT | android.intent.action.EDIT | 编辑指定数据 |
ANTION_DIAL | android.intent.action.DIAL | 显示拨号界面 |
ACTION_CALL | android.intent.action.CALL | 直接向指定用户打电话 |
ACTION_SEND | android.intent.action.SEND | 向其他人发送数据 |
ACTION_SENDTO | android.intent.action.SENDTO | 向其他人发送信息 |
Data(数据)和Type(类型)
data属性通常用于向action属性提供操作的数据,接收一个Uri的对象。
如上文打开网页的隐式Intent,其中地址就是一个data属性。
Uri的对象总是满足如下格式:
scheme://host:port/path
常见的Uri对象例如:
http://www.baidu.comtel:13813801380content://com.android.contacts/contacts/1
也可以用方法在intent中设置:
intent.setData(Uri.parse("scheme://host:port/path"));
type属性用于指定该data属性所指定Uri对应的MIME类型(符合abc/xyz合适的字符串)。
intent.setType("abc/xyz");
需要注意的是data与type属性会互相覆盖, 后设置属性覆盖先设置的属性,如果要同时设置这两个属性则需要调用:
intent.setDateAndType(Uri.parse("scheme://host:port/path","abc/xyz");
这两个属性声明在intent-filter元素中格式:
<data android:mimeType=""//声明所能匹配Intent的Type属性 android:scheme=""//声明所能匹配Intent的Data属性scheme部分 android:host=""//声明所能匹配Intent的Data属性host部分 android:port=""//声明所能匹配Intent的Data属性port部分 android:path=""//声明所能匹配Intent的Data属性path部分 android:pathPrefix=""//声明所能匹配Intent的Data属性path前缀 android:pathPattern=""/>//声明所能匹配Intent的Data属性path字符串模板
ps1:只有intent添加的属性都符合intent-filter中的属性,才会启动该组件;
ps2: host、port、path属性需要依次指定,可以省略后者,但不能省略前者。即如果只指定port属性,而没有指定host属性,那么android:prot属性不会起作用;
Extra(扩展)
extra属性值是一个Bundle对象,即上文说到的传递数据。
上文方法中直接传入键值对的数据,其实方法内部也是先创建一个Bundle对象,再把数据传入,本质intent传递的是Bundle对象。
Flag(标志)
flag属性用于为该intent添加额外的控制旗标,通过调用:
intent.addFlags(int flags);
常用的Flag:
FLAG_ACTIVITY_BROUGHT_TO_FRONT:如果该Flag启动的Activity已经存在,下次再次启动时,只是把该Activity带到前台;
FLAG_ACTIVITY_CLEAR_TOP:相当于启动模式singleTask;
FLAG_ACTIVITY_SINGLE_TOP:相当于启动模式singleTop;
FLAG_ACTIVITY_NEW_TASK:默认的旗标;
FLAG_ACTIVITY_NO_ANIMATION:启动Activity是不会使用过场动画;
FLAG_ACTIVITY_NO_HISTORY: 启动的Activity不会保留在栈中;
更多相关文章
- Android(安卓)ImageView 的scaleType 属性图解
- Android用户界面开发(9):日期和时间
- Android中的控件
- Android属性动画ValueAnimator源码简单分析
- AndroidUI设计之 布局管理器 - 详细解析布局实现
- 以一个小程序设计来入门Android
- 【多图】Google工程师解析Android系统架构
- Android系列教程之六:TextView小组件的使用--附带超链接和跑马灯
- Android控件之利用selector自定义的带文字的图片按钮