Intent属性详解

来源:互联网 发布:eviews软件中文版下载 编辑:程序博客网 时间:2024/05/20 00:17

Intent提供了一种通用的消息系统,它允许在你的应用程序见传递Intent来执行动作和产生事件,使用Intent可以激活Android应用的三种类型的核心组件:活动Activity、服务Service、广播接受者Broadcast

Intent分为显示Intent和隐式Intent,区别是:显式Intent需要指定要启动的Activity,而隐式Intent则是指定一些条件,android会自动替我们找出符合这些条件的Activty

或者说区别是:有没有指定Component属性

下面逐一介绍Intent的属性以及intent-filiter配置

首先我们必须清楚,<intent-filiter>标签里面,只有三个属性<data>,<action>,<category>,其余属性(extra,flag)是在intent里面设置的

Component属性:

Intent的Component属性需要接受一个ComponentName对象,从而唯一的确定要启动的类

package test;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.os.Bundle;public class MyActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ComponentName component = new ComponentName(MyActivity.this, SecondActivity.class);Intent intent = new Intent();//为intent设置componentintent.setComponent(component);startActivity(intent);}}

可以看出,指定了Component属性以后,<intent-filiter>元素基本没有什么意义了

在secondActiivty里面,我们还以获取这个ComponentName对象

package test;import android.app.Activity;import android.content.ComponentName;import android.os.Bundle;public class SecondActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ComponentName componentName = getIntent().getComponent();//获取被启动对象的包名,也就是当前包名componentName.getPackageName();//获取被启动对象的类名,也就是当前类名componentName.getClassName();}}


Action、Category属性

Action、Catrgory属性都是一个普通的字符串,通常两者结合使用

我们在AndroidManifest.xml文件的<Activity>的<Intent-filiter>中配置相应的属性

其中<action>,<category>子元素可以包含0个或多个

每个Intent对象最多只能包含一个Action属性,但是可以包含多个Category属性(其中有一个默认值为android.intent.category.DEFAULT)

一个过滤器必须至少包含一个<action>子元素,否则它将阻塞所有的intents。

如果Intent对象没有指定动作,将自动通过检查(只要过滤器至少有一个过滤器,否则就是上面的情况了)

所以在<intent-filiter>标签里面,至少有如下标签

<category android:name="android.intent.category.LAUNCHER" />
只要一个种类在过滤器列表中没有,就算种类检测失败

只有<action>与<catrgory>都匹配的intent才能启动对于的activty

下面为intent设置这个两个属性的值

public class MyActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Intent intent = new Intent();intent.setAction("m_action");intent.addCategory("m_category1");startActivity(intent);}}
对应能够启动的activity应该在<intent-filiter>里面有如下配置,注意其中<category android:name="android.intent.category.DEFAULT" />             
是必须的

  <activity            android:name=".SecondActivity">            <intent-filter>                <action android:name="m_action" />                <category android:name="m_category1" />                <category android:name="m_category2" />                <category android:name="android.intent.category.DEFAULT" />                          </intent-filter>        </activity>
同理,在secondActivity里面我们也可以获取这些属性值

public class SecondActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);String action = getIntent().getAction();Set<String> cates = getIntent().getCategories();}}

Data、Type属性

Data属性向Action属性提供操作的数据Data属性接受一个Uri对象,Uri字符串总满足一下格式

scheme://host:port/path

Type属性用于指定Data所指定Uri对应的MIME类型,这种MIME类型可以是任何自定义的MIME类型,只要符合abc/xyz格式的字符串即可

另外DATA属性跟TYPE属性会相互覆盖,例如先设置DATA,然后设置TYPE,那么TYPE就覆盖DATA,反之亦然

如果想要两者都设置,那么可以使用setDataAndType()方法

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Intent intent = new Intent();//TYPE覆盖DATAintent.setData(Uri.parse("lee://www.test:8888/test"));intent.setType("abc/xyz");//DATA覆盖TYPEintent.setData(Uri.parse("lee://www.test:8888/test"));intent.setType("abc/xyz");//TYPE、DATA同时设置intent.setDataAndType(Uri.parse("lee://www.test:8888/test"), "abc/xyz");startActivity(intent);}
在AndroidManifest.xml文件中,为组件声明DATA,TYPE属性,格式如下:

            <data android:mimeType=""                    android:scheme=""                    android:host=""                    android:port=""                    android:path=""                    android:pathPrefix=""                    android:pathPattern=""/>
TYPE属性要求与<data>中的mimeType属性相同,才能启动该组件,Intent对象和过滤器都可以用"*"通配符匹配子类型字段,例如"text/*","audio/*"表示任何子类型。

而DATA属性匹配过程则有些差别:

Data属性的Uri对象实际可分为scheme,host,port和path部分,此时并不要求这四个部分的值必须和<data../>子元素android:scheme,android:host,android:port,android:path

完全满足。有以下匹配条件:

1.如果目标组件<data.../>子元素只指定android:scheme属性,那么只要Intent的Data属性的scheme部分与android:scheme属性值相同,即可启动该组件。

2.如果目标组件<data.../>子元素只指定android:scheme属性,android:host属性,那么只要Intent的Data属性的scheme,host部分与android:scheme,android:host属性值相同

,即可启动该组件。

3.如果目标组件<data.../>子元素只指定android:scheme属性,android:host,android:port属性,那么要求Intent的Data属性的scheme,host,port部分与android:scheme,android:host,android:port属性值相同,即可启动该组件。

4.如果目标组件<data.../>子元素只指定android:scheme,android:host,android:path,属性,那么只要求Intent的Data属性的scheme,host,path部分与android:scheme,android:host,android:path的属性值相同,即可启动该组件。            

5.如果目标组件<data.../>子元素只指定android:scheme,android:host,android:port, android:path,属性,那么就要求Intent的Data属性的scheme,host,port,path部分依次

与android:scheme,android:host,android:port,android:path的属性值相同,即可启 动该组件。


这里主要说的区别是 path、pathPrefix、pathPattern 之间的区别

path 用来匹配完整的路径,如:http://example.com/blog/abc.html,这里将 path 设置为 /blog/abc.html 才能够进行匹配;

  • pathPrefix 用来匹配路径的开头部分,拿上来的 Uri 来说,这里将 pathPrefix 设置为 /blog 就能进行匹配了;
  • pathPattern 用表达式来匹配整个路径,这里需要说下匹配符号与转义。
匹配符号:
  1. “*” 用来匹配0次或更多,如:“a*” 可以匹配“a”、“aa”、“aaa”...
  2. “.” 用来匹配任意字符,如:“.” 可以匹配“a”、“b”,“c”...
  3. 因此 “.*” 就是用来匹配任意字符0次或更多,如:“.*html” 可以匹配 “abchtml”、“chtml”,“html”,“sdf.html”...
转义:因为当读取 Xml 的时候,“/” 是被当作转义字符的(当它被用作 pathPattern 转义之前),因此这里需要两次转义,读取 Xml 是一次,在 pathPattern 中使用又是一次。如:“*” 这个字符就应该写成 “//*”,“/” 这个字符就应该写成 “////”。


Extra属性

Extra属性用于在多个Action之间进行数据交换,extra的属性值应该是一个Bundle对象,Bundle对象就像一个Map对象,有自己的key-value


Flag属性

可以通过FLAG属性为intent添加一些额外的控制旗标,例如:

intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
下面来解释一下常用的flag旗标

1,FLAG_ACTIVITY_BROUGHT_TO_FRONT:如果通过该flag启动的Activity已经存在,下次启动时,将只是将该Activity带到前台。

栈中:ABCD->(CALLB)->ACDB

2,FLAG_ACTIVITY_CLEAR_TOP:通过该flag启动的Activity将会把要启动的Activity之上的Activity全部弹出栈

栈中:ABCD->(CALLB)->AB

3,FLAG_ACTIVITY_NEW_TASK:默认flag,将重新创建一个新的Activity

栈中:ABCD->(CALLB)->ABCDB

4,FLAG_ACTIVITY_NO_ANIMATION:该flag控制启动Activity时不使用过渡动画

5,FLAG_ACTIVITY_NO_HISTORY:该flag控制被启动的Activity不会保留在栈中

栈中:ABCD->(CALLE)->ABCE

6,FLAG_ACTIVITY_PEORDER_TO_FRONT:如果当前已有该Activity,直接将该Activity带到前台

栈中:ABCD->(CALLB)->ACDB

7,FLAG_ACTIVITY_SINGLE_TOP如果当前栈顶Activity就是要启动的Activity,则直接使用栈顶

栈中:ABCD->(CALLD)->ABCD


Intent解析机制

Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有<intent-filter>及其中定义的Intent,通过PackageManager(注:PackageManager能够得到当前设备上所安装的
application package的信息)来查找能处理这个Intent的component。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:
1.1  如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;
1.2  如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
1.3  如果Intent中的数据不是content:类型的URI,而且Intent也没有明确指定type,将根据Intent中数据的scheme(比如 http:或者mailto:)进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。
1.4 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。

0 0