Android Basic Intent

本技术点学习指导说明

Android的基本设计理念是鼓励减少组件间的耦合,因此Android提供了Intent。Intent提供了一种通用的消息系统,它允许在你 的应用 程序与其他应用程序间传递Intent来执行动作和产生事件。使用Intent可以激活Android应用的三个核心组件:Activity、 Service&Broadcastreceiver。

Intent简介

Intent组件不是四大组件,但却是连接四大组件的媒介

Intent的中文意 思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动 作、动作涉及数据、附 加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。

Intent可以划分为显式Intent和隐式Intent。

  • 显式Intent:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显示Intent。其明确指定了Intent应该传递给哪个组件。
  • 隐式Intent:没有明确指定组件名的Intent为隐式Intent。Android系统会根据隐式Intent中设置的Action、Category、Data找到最合适的组件来处理这个Intent

Intent传输机制

Android的三个基本组件——Activity,Service和Broadcast Receiver——都是通过Intent机制激活的,不同类型的组件有不同的传递Intent方式:

  1. Activity:一个intent对象传递给Context.startActivity()或Activity.startActivityForRestult()去启动一个活动或使一个已存在的活动去做新的事情。
  2. Service:一个intent对象传递给Context.startService()去初始化一个service或传递一个新的 指令给正在运行的service或者将一个intent传递给Context.bindService()去建立调用组件和目标服务之间的连接。
  3. Broadcast Receiver:一个intent对象传递给任何广播方法 (如 Context.sendBroadcast(),Context.sendOrderedBroadcast(),Context.sendStickyBroadcast()), 都 将传递到所有感兴趣的广播接收者。 在每种情况下,Android系统查找合适的activity、 service、 broadcastreceivers来响应意图,如果有必要的话,初始化他们。这些消息系统之间没有重叠,即广播意图仅会传递给广播 接收者,而不会传递 活动或服务,反之亦然。

Intent的属性

  • component(组件):目的组件
  • action(动作):用来表现意图的行动
  • category(类别):用来表现动作的类别
  • data(数据):表示与动作要操纵的数据
  • ype(数据类型):对于data范例的描写
  • extras(扩展信息):扩展信息
  • Flags(标志位):期望这个意图的运行模式

下面分别详细介绍一下Intent的属性:

1.  Action:使用android:name特性来指定对响应的动作名。动作名必须是独一无二的字符串。SDk中定义了一些标准的动作,但也可以根据相应的Actvity自定义动作。Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的Activity 定义时,可以在其 <intent-filter >节点指定一个 Action列表用于标识 Activity 所能接受的“动作”。

SDK中定义了一些标准的Action常量如下表所示:

Constant

Target component

Action

ACTION_CALL

activity

Initiate a phone call.

ACTION_EDIT

activity

Display data for the user to edit.

ACTION_MAIN

activity

Start up as the initial activity of a task, with no data input and no returned output.

ACTION_SYNC

activity

Synchronize data on a server with data on the mobile device.

ACTION_BATTERY_LOW

broadcast receiver

A warning that the battery is low.

ACTION_HEADSET_PLUG

broadcast receiver

A headset has been plugged into the device, or unplugged from it.

ACTION_SCREEN_ON

broadcast receiver

The screen has been turned on.

ACTION_TIMEZONE_CHANGED

broadcast receiver

The setting for the time zone has changed.


2.  Category:被执行动作的附加信息。如:CATEGORY_HOME则表示回到Home界面。

SDK文档中关于Category的信息如下表所示:

Constant

Meaning

CATEGORY_BROWSABLE

The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message.

CATEGORY_GADGET

The activity can be embedded inside of another activity that hosts gadgets.

CATEGORY_HOME

The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed.

CATEGORY_LAUNCHER

The activity can be the initial activity of a task and is listed in the top-level application launcher.

CATEGORY_PREFERENCE

The target activity is a preference panel.


Category属性也是作为<intent-filter>子元素来声明的,例如:

<intent-filter>

  <action android:name="com.vince.intent.MY_ACTION"></action>

  <category android:name="com.vince.intent.MY_CATEGORY"></category>

  <category android:name="android.intent.category.DEFAULT"></category>

</intent-filter>

Action和Category通常是放在一起的。注:如果没有指定的category,则必须使用默认的DEFAULT也就是说:只 有<action>和<category>中的内容同时能够匹配上Intent中指定的action和category时,这 个 活动才能响应Intent。

如果使用的是DEFAULT这种默认的category,在稍后调用startActivity()方法的时候会自动将这个 category添加到Intent中。

3.  Data:也就是执行动作要操作的数据(URI和MIME类型),不同的Action有不同的Data数据指定。比如:ACTION_VIEW要显示的应用应该和URI匹配。

4.  type:显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式 指定的类型而不再进行推导。Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判 定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。

如果Intent对象中既包含Uri又包含Type,那么,在<intent-filter>中也必须二者都包含才能通过测试。

Type属性用于明确指定Data属性的数据类型或MIME类型,但是通常来说,当Intent不指定Data属性时,Type属性才会起作用,否则Android系统将会根据Data属性值来分析数据的类型,所以无需指定Type属性。

data和type属性一般只需要一个,通过setData方法会把type属性设置为null,相反设置setType方法会把data设置为null,如果想要两个属性同时设置,要使用Intent.setDataAndType()方法。

5.  extras:是其它所有附加信息的集合,主要用于传递目标组件所需要的额外数据。附加信息可以使用putExtras()和getExtras()作为Bundle来读和写。

6.  Flags:期望这个意图的运行模式,常用于Activity的场景中,和Activity的启动模式有着密切的关系。如Intent.FLAG_ACTIVITY_NEW_TASK,默认的跳转类型,它会重新创建一个新的Activity。

Android如何解析Intent

Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent, 最终找到匹配的Intent。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的, 判断方法如下:

如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;

如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。

如果Intent中的数据不是content: 类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme (比如 http: 或者mailto: ) 进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。

如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。

IntentFilter

IntentFilter类表示Intent过滤器, 大部分情况下, 每一个component都会定义一个或多个IntentFilter,用于表明其可处理的Intent。
一般来说,component的IntentFilter应该在AndroidManifest.xml文件中定义。

定义的方法:

在<activity>,<receiver>, <service>元素中增加一个或多个<intent-filter>子元素。如:
<!-- 声明作为程序入口的Activity-->
<activityandroid:name=".FirstActivity">
       <intent-filter>
               <action android:name="android.intent.action.MAIN"/>
               <category android:name="android.intent.category.LAUNCHER"/>
       </intent-filter>
</activity>

关于IntentFilter的几点注意事项

(1).android.intent.action.MAIN 与 android.intent.category.LAUNCHER

android.intent.action.MAIN决定一个应用程序最先启动那个组件

android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里(说白了就是是否在桌面上显示一个图标)

这两个属性组合情况:

第一种情况:有MAIN,LAUNCHER,程序列表中无图标

原因:android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里 

第二种情况:无MAIN,LAUNCHER,程序列表中无图标

原因:android.intent.action.MAIN决定应用程序最先启动的Activity,如果没有Main,则不知启动哪个Activity,故也不会有图标出现

所以这两个属性一般成对出现。

如果一个应用中有两个组件intent-filter都添加了android.intent.action.MAIN和

android.intent.category.LAUNCHER这两个属性, 则这个应用将会显示两个图标, 写在前面的组件先运行。


(2).关于隐式intent

  每一个通过 startActivity() 方法发出的隐式 Intent 都至少有一个 category,就是 "android.intent.category.DEFAULT",所以只要是想接收一个隐式 Intent 的 Activity 都应该包括 "android.intent.category.DEFAULT" category,不然将导致 Intent 匹配失败.

比如说一个activity组件要想被其他组件通过隐式intent调用, 则其在manifest.xml中的声明如下:

<activity android:name="com.gesture.QGestureListActivity">

     <intent-filter>  

           <action android:name="com.google.test" />

           <category android:name="android.intent.category.DEFAULT" />

 </intent-filter> 

</activity>


(3).关于intent-filter匹配优先级

首先查看Intent的过滤器(intent-filter),按照以下优先关系查找:action->data->category


(4).android.intent.category.LAUNCHERandroid.intent.category.HOME的区别

android.intent.category.LAUNCHERandroid.intent.category.LAUNCHER决定应用程序是否显示在程序列表里,就是android开机后的主程序列表。

android.intent.category.HOME:按住“HOME”键,该程序显示在HOME列表里。

经验分享

通过intent启动拨号,联系人和短息应用

android使用Intent传递对象

Android系统中标准Intent的使用

posted @ 2017-05-12 10:39  奔跑的蚂蚁aa  阅读(150)  评论(0编辑  收藏  举报