Intent的使用详解

在android中,Intent的使用可算是无处不在,它起到了媒介的作用,可以当做一条指令,或者一种协议。它的作用是告诉android系统要做什么和怎么做


该Intent对象组要由六部分,分别是Component name,Action,Data,Category,Extras以及Flags。那么这些部分分别起到什么作用,以及在何时应该如何使用呢,下面做一下简单的讲解。


1,Component name

顾名思义,这指的是组件的名称。即要把该Intent对象传递给它的那个组件。组件名称对象由ComponentName类来描述,包含包名称和类名称,并且该组件肯定会被声明在AndroidManifest.xml中。

组件名称通过 setComponent(),setClass(),setClassName()设置,通过getComponent()获取。


需要注意的是Component name是一个可选项,如果被设置,那么Intent对象就显式指定了要转向的组件,如果没有被设置,则Intent对象需要根据其他信息进行筛选查找。


例如:当前有LocalService1和LocalService2两个Service,并在AndroidManifest.xml文件中的配置如下:

<service android:name=".services.LocalService1">
      <intent-filter>
          <action android:name="com.example.test.LocalService1" />
      </intent-filter>
</service> 

<service android:name=".services.LocalService2">
       <intent-filter>
           <action android:name="com.example.test.LocalService2" />
        </intent-filter>
</service>

String packageName = getPackageName() ;
String className = LocalService2.class.getName() ;
ComponentName component = new ComponentName(packageName, className);

Intent intent = new Intent() ;

intent.setComponent(component) ;

intent.setClassName(packageName,className) ;

这我们指定了Intent会被发送到的对象为LocalService2


2,Action

这个指定的是一个动作,它是一个字符串类型。在Intent类里面定义了很多有关Action的常量,这些常量对应的都是Android系统提供的一些供用户使用的功能。当然我们是可以自定义Action的,只需要定义一个字符串即可,但是需要注意的是,该字符串应该使用你的应用的包名作为前缀!


Action这部分的内容十分的关键,应该它会决定其它部分的内容如何构造,例如这个动作是“发邮件”,那么其它部分的内容就需要安装“邮件”的协议来构造数据。 Action的不同,主要会影响Data和

Extras的不同。


Action的设置方式如下:

Intent intent = new Intent() ;
intent.setAction("com.example.test.LocalService2") ;

请思考,如果使用以下的方式来设置Intent,会启动哪个Service

String packageName = getPackageName() ;
String className = LocalService1.class.getName() ;
Intent intent = new Intent() ;
intent.setClassName(packageName,className) ; 

intent.setAction("com.example.test.LocalService2") ;

答案是启动LocalService1,只有没有设置Component name才会按照Action去查找。


3,Data

在讲Data之前,先说说URI(统一资源标识符)。

互联网上(包括本地)有许多的资源,包括图片,视频,程序等等,然而我们需要一种统一的标准来定位各样的资源,这就是URI,它其实就是一个字符串而已。我们可以通过URI使用特定的协议和资源进行交互。 

URI文法结构: URI协议名:协议对应的内容

URI协议名有很多,例如:http, ftp,mailto,file等等,每一种协议都决定了协议内容的语法和语义,例如,如果是http协议,那么协议内容就要指定主机名,端口号,资源路径等;如果是mailto协议,那么协议内容就需要指定邮箱地址等。

在android中,动作和数据是匹配的,Data描述的是相应动作要处理的数据资源信息。Data所包含的内容如下:

<data android:scheme=""/>
<data android:host=""/>
<data android:port=""/>
<data android:mimeType=""  />
<data android:path=""/>
<data android:pathPrefix=""/>

<data android:pathPattern=""/>
<data android:ssp=""/>
<data android:sspPrefix=""/>
<data android:sspPattern=""/>

那么在使用的时候哪些需要设置,哪些不需要设置呢? 这其实和使用Intent的那个组件有关,如果那个组件是浏览器,那么我们可能就需要可以主机,端口号,路径等信息。

如果AndroidManifest.xml文件中的配置为:

<service android:name=".services.LocalService2">
         <intent-filter>
            <action android:name="com.example.test.LocalService2" />
            <category android:name="android.intent.category.DEFAULT" />

            <data android:scheme="file"/> 

            <data android:mimeType="text/html"  />
         </intent-filter>

</service>

在intent-filter中指定data属性的实际目的是:要求接收的Intent中的data必须符合intent-filter中指定的data属性,这样达到反向限定Intent的作用。


那么在启动这个Service的时候,Intent的写法如下:

Intent intent = new Intent() ;
intent.setAction("com.example.test.LocalService2") ;
Uri uri =  Uri.parse("file://com.android.test:500/mnt/sdcard");  
 intent.setDataAndType(uri, "text/html") ;

data属性解析:android:scheme、android:host、android:port、android:path、android:mimeType
data的前四个属性构成了URI的组成部分,mimeType设置了数据的类型
data元素组成的URI模型如下:

scheme://host:port/path

举例说明(URI ):

 file://com.android.test:500/mnt/sdcard

scheme-->file:
host-->com.android.test
port-->500
path-->mnt/sdcard


其中host和port为URI的authority,如果没有指定host,port将被忽略。


data的各属性并不是独立的,data的各属性构成了URI的整个组成部分。要使authority(host和port)有意义,必须指定scheme;要使path有意义,必须使scheme和authority(host和port)有意义。


URI和intent-filter匹配:
Intent中URI和intent-filter进行比较的时候只会进行部分的比较:
(1)当intent-filter中只设置了scheme,只会比较URI的scheme部分;
(2)当intent-filter中只设置了scheme和authority,那么只会匹配URI中的scheme和authority;
(3)当intent-filter中设置了scheme、authority和path,那么只会匹配URI中的scheme、authority、path;(path可以使用通配符进行匹配)
(4)当intent-filter中设置了mimeType,还会进行数据类型的匹配。



常用的Data的URI格式如下:

tel://:号码数据格式,后跟电话号码。 
mailto://:邮件数据格式,后跟邮件收件人地址。
smsto://:短息数据格式,后跟短信接收号码。
content://:内容数据格式,后跟需要读取的内容。 
file://:文件数据格式,后跟文件路径。
market://search?q=pname:pkgname:市场数据格式,在Google Market里

                                                              搜索包名为pkgname的应用。
 geo://latitude,longitude:经纬数据格式,在地图上显示经纬度指定的位置。



4,Category

Intent中的类别是一种被执行动作的额外信息。Category是一个字符串,在Intent中提供了一些默认的Category字符串常量。例如 LAUNCHER_CATEGORY 表示Intent 的接受者应该在Launcher中作为顶级应用出现;而ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个,这些动作可以在同一块数据上执行。

常用的CATEGORY常量及说明:

   CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。 
 CATEGORY_HOME:设置该组件为Home Activity。
 CATEGORY_PREFERENCE:设置该组件为Preference。 
 CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,

                                            通常为入口ACTION_MAIN配合使用。 
 CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。 
 CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。


5,Extras

附加信息,是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。

    

6,Flags

预定义一系列用来控制Intent行为的属性值。

intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);

如果activity在task存在,拿到最顶端,不会启动新的Activity

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

如果activity在task存在,将Activity之上的所有Activity结束掉

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

默认的跳转类型,将Activity放到一个新的Task中

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

如果Activity已经运行到了Task,再次跳转不会在运行这个Activity


你可能感兴趣的:(android,intent,详解)