Android Intent机制

来源:互联网 发布:淘宝千人千面 编辑:程序博客网 时间:2024/06/02 05:00

Android的四大组件:

  • Activity
  • Service
  • Broadcast Receiver
  • Content Provider

1.Intent(意图,意向)介绍

官方描述:
Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed.
   在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的 交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。
  Intent是组件之间的通信纽带,Intent是一种运行时绑定机制(run-time binding),他能在程序运行过程中,连接两个不同的组件。通过Intent,程序可以向Android表达某种请求或者意愿,Android会根据Intent 的内容选择适当的组件来完成请求。

2.Intent 的作用:

Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯。intent主要是用来启动其他的 activity 或者service,所以可以将intent理解成activity之间的粘合剂。

3.Intent 的组成:

IntentStructure
The primary pieces of information in an intent are:

  1. action
    The general action to be performed, such as
    ACTION_VIEW,ACTION_EDIT,ACTION_MAIN
  2. data
    The data to operate on, such as a person record in the contacts database, expressed as a “android.net.Uri”

Intent主要包含
动作 – Action:用来指明要实施的动作是什么。
数据 – Data:一般是uri类型,还有一个Extra用来传递额外的信息;

In addition to these primary attributes, there are a number of secondary attributes that you can also include with an intent:
category: gives additional information about the action to execute. For example,”CATEGORY_LAUNCHER”means it should appear in the Launcher as a top-level application, while”CATEGORY_ALTERNATIVE” means it should be included in a list of alternative actions the user can perform on a piece of data;
type: Specifies an explicit type (a MIME type) of the intent data. Normally the type is inferred from the data itself. By setting this attribute, you disable that evaluation and force an explicit type.
component: Specifies an explicit name of a component class to use for the intent. Normally this is determined by looking at the other information in the intent (the action, data/type, and categories) and matching that with a component that can handle it. If this attribute is set then none of the evaluation is performed, and this component is used exactly as is. By specifying this attribute,all of the other Intent attributes become optional.
extras:This is a {@link Bundle} of any additional information.This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body。

Category 分类 :一个字符串,包含了关于处理该intent的组件的种类的信息。一个intent对象可以有任意个category。
Type 类型 :显式指定Intent的MIME数据类型。
Component 组件:指定Intent的目标组件的类名称。
extras 附加额外:添加Bundle附件额外的数据

下面一一讲解:

1.Action
Intent有很多Action
这里写图片描述
在Mainfest文件中使用IntentFilter设置
这里写图片描述

<activity android:name=".BainActivity">  <intent-filter>  <!--拨号-->      <action android:name="android.intent.action.DIAL" /> </intent-filter></activity>
//Activity启动一个IntentIntent intent = new Intent("android.intent.action.DIAL");startActivity(intent);//这时启动的就是.BainActivity

2.Data/Extras

 //打开指定的网页 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.baidu.com")); //打开网页进行关键字搜索,浏览器会按照自己设置的默认 的搜索引擎进行搜索 Intent intent2 = new Intent(Intent.ACTION_WEB_SEARCH);   intent.putExtra(SearchManager.QUERY," 马云"); //Extras传递String类型的信息 Intent intent3 = new Intent(this,BainActivity.class); intent.putExtra("UserName","JiangYiYan"); intent.putExtra("PWD","CaiCaiJYY"); //Extras传递Bundle信息 Intent intent4 = new Intent(this,BainActivity.class); Bundle bundle = new Bundle(); bundle.putString("QName","YiDongYI"); bundle.putString("QID","298801"); intent4.putExtras(bundle);  //or intent4.putExtra("info",bundle);//打电话 Intent intent5 = new Intent(Intent.ACTION_CALL);   intent.setData(Uri.parse("tel:1342347098"));   //启动 startActivity(intent);

我们可以将一个指定前缀的字符串转换成 特定的URI类型,如:“http:”或“https:”表示网络地址类型,“tel:”表示电话号码类型,“mailto:”表示邮件地址类型,等等。那么我们如何知道目标是否接受这种前缀呢?这就需要看一下目标中元素的匹配规则了。
在目标标签中包含了以下几种子元素,他们定义了url的匹配规则:
android:scheme 匹配url中的前缀,除了“http”/”https”/”tel”…之外,我们可以定义自己的前缀
android:host 匹配url中的主机名部分,如“baidu.com”,如果定义为“*”则表示任意主机名
android:port 匹配url中的端口
android:path 匹配url中的路径

 //Activity的声明信息 <activity android:name=".BainActivity">   <intent-filter>      <action android:name="com.scott.intent.action.TARGET"/>      <category android:name="android.intent.category.DEFAULT"/>      <data android:scheme="scott"             android:host="com.scott.intent.data"           android:port="7008"           android:path="/target"/>      </intent-filter>   </activity> //这是我们需要指定action和data,缺一不可Intent intent = new Intent("com.scott.intent.action.TARGET");     intent.setData(Uri.parse("scott://com.scott.intent.data:7008/target"));  //uri中的每个部分和BainActivity配置信息中全部一致才能跳转成功,否则就被系统拒绝。startActivity(intent);

3.Category

<category android:name="android.intent.category.LAUNCHER" />  // 代表该目标Activity是该应用所在task中的初始Activity并且出现在系统launcher的应用列表中。

Android中Category:
这里写图片描述
如何使用Category:
当我们需要回到Home页面时:

Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME);startActivity(intent);

4.Type 类型
描述执行动作的目标Activity所能处理的MIME数据类型。

<intent-filter>  <action android:name="android.intent.action.MAIN" />  <action android:name="android.intent.action.DIAL" />  <data android:mimeType="imge/*"/>  //string/accept = "imge/*"  <data android:mimeType="@string/accept"/>  <category android:name="android.intent.category.LAUNCHER" /></intent-filter>

在使用Intent进行匹配时,我们可以使用setType(String type)或者setDataAndType(Uri data, String type)来设置mimeType。

 Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); intent.setType("imge/*"); intent.setDataAndType(Uri.parse("http://image.baidu.com/"),"imge/*"); startActivity(intent);

5.Component 类型

Intent intent = new Intent(Intent.ACTION_MAIN); //匹配同一包内的目标intent.setComponent(new ComponentName(getApplicationContext(), BainActivity.class));intent.setComponent(new ComponentName(this, BainActivity.class));intent.setComponent(new ComponentName(getApplicationContext(),"com.lisxhs.kuaiyue.BainActivity"));//匹配其他包内的目标,参数1是包名,参数2是类名intent.setComponent(new ComponentName("com.lisxhs.kuaiyue","com.lisxhs.kuaiyue.BainActivity"));//如果我们在Intent中指定了component属性,系统将不会再对Action/data/type、category进行匹配。startActivity(intent);

Intent解析

IntentResolution
There are two primary forms of intents you will use.
Explicit Intents
have specified a component “setClass”,“setComponent”,which provides the exact class to be run. Often these will not include any other information, simply being a way for an application to launch various internal activities it has as the user interacts with the application.
Implicit Intents
have not specified a component,instead, they must include enough information for the system to determine which of the available components is best to run for that intent.
When using implicit intents, given such an arbitrary intent we need to know what to do with it.
This is handled by the process of Intent resolution which maps an Intent to an : android.app.Activity/ Broadcast Receiver/ android.app.Service or sometimes two or more activities/receivers that can handle it.
The intent resolution mechanism basically revolves around matching an Intent against all of the intent-filter descriptions in the installed application packages.There are three pieces of information in the Intent that are used for resolution: the action, type, and category. Using this information, a query is done on the PackageManager for a component that can handle the
intent. The appropriate component is determined based on the intent information supplied in the AndroidManifest.xml file as
follows:

意图的解析:
有两种形式的意图:
显示意图:通过setClass或者是setComponent设置了精确的组件,明确的知道要启动的类或组件,这一类一般不在包含其他的信息;
隐式意图:没有明确的指出组件,这是就需要Intent提供其他的信息,需要足够的信息去确定Intent需要启动的组件。当使用隐式意图的时候,我们主要是通过匹配活动、广播和服务,有时候或则是匹配两种以上的组件才能够找到Intent期望的动作。
Intent的解决机制是:通过intent-filter的描述安装App。
主要通过三个属性去确定:action、type、category,用这些信息去查询PackageManagerAndroidManifest.xml

Intent解析机制:主要是通过查找已注册在AndroidManifest.xml中的所有及其中定义的Intent,通过PackageManager(注:PackageManager能够得到当前设备上所安装的
application package的信息)来查找能处理这个Intent的component

原创粉丝点击