Intent技术简介

来源:互联网 发布:dialog linux 编辑:程序博客网 时间:2024/05/22 09:02
Intent
java.lang.Object
        android.content.Intent
An intent is an abstract description of an operation to be performed. 
It can be used with startActivity  to launch an Activity, 
broadcastIntent  to send it to any interested BroadcastReceiver  components, 
and startService(Intent)  or bindService(Intent, ServiceConnection, int) to communicate with a background Service.
An 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. 

Intent用于描述用户想要执行的操作。
它主要要用于三个方面:
1,启动活动。Activity。
2,广播的处理。broadcast
3,启动和绑定服务。Service

intent的两个主要元素是如下:
action -- The general action to be performed, such as ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, etc.
动作
data -- The data to operate on, such as a person record in the contacts database, expressed as a Uri.
数据


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.
    这个元素只是和data配合适用。用来显式的说明data的数据类型
组件: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.
        该元素用于显示的intent,确定了哪个组件类在处理该intent。它和(the action, data/type, and categories)是互斥的。
        使用了该元素,其他的元素就是可选的了。

额外数据:extras -- This is a 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, etc.
    它是个Bundle用于存储额外的数据信息。
    
There are a variety of standard Intent action and category constants defined in the Intent class, 
but applications can also define their own.
在Intent类中有大量Intent action and category的定义,但是用户也可以定义自己的action和category。
常用的Intent可参考《常用Intent

Intent有两种调用方式:
Explicit Intents显式):It have specified a component (via setComponent(ComponentName) or setClass(Context, Class)), 
                        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.
                        该方式通过setComponent(ComponentName) or setClass(Context, Class)明确的来指定是哪个组件类来在处理该intent。
                        即它通过指定组件(component)这个元素来确定谁处理这个intent。经常它不再包含其他信息。
                        【组件(component)这个元素应该和the action, data/type, and categories这四个元素是互斥的】

                        【Activity,Service用setClass的方式可以,但是broadcast不行】
Implicit Intents(隐式):It 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. 
                        该方式没有指定哪个具体的组件来处理该intent,但是它提供了足够的信息,以便系统来确定哪个组件在处理。
对于显示Intent,Android不需要去做解析,因为目标组件已经很明确,Android需要解析的是那些隐式Intent,通过解析,
将 Intent映射给可以处理此Intent的Activity、IntentReceiver或Service。
Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的 Intent。
在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的.


应用程序的组件为了告诉Android自己能响应、处理哪些隐式Intent请求,
可以声明一个甚至多个I
ntent Filter。每个Intent Filter描述该组件所能响应Intent请求的能力——组件希望接收什么类型的请求行为,
什么类型的请求数据.如何为组件声明自己的Intent Filter? 常见的方法是在AndroidManifest.xml文件中用属性<Intent-Filter>描述组件的
Intent Filter。
隐式Intent(Explicit Intents)和Intent Filter(Implicit Intents)进行比较时的三要素是Intent的动作、数据以及类别
实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面的检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给目标组件。

接下来我们讲解这三方面检查的具体规则。
1.动作匹配
<intent-filter>元素中可以包括子元素<action>,比如:
<intent-filter>
<action android:name=”com.example.project.SHOW_CURRENT” />
<action android:name=”com.example.project.SHOW_RECENT” />
<action android:name=”com.example.project.SHOW_PENDING” />

</intent-filter>
一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和 该<intent-filter>匹配。
如果Intent请求的Action和<intent-filter>中个某一 条<action>匹配,那么该Intent就通过了这条<intent-filter>的动作测试。
如果Intent请求 或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。

(1) 如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent- filter>匹配。
(2) 反之,如果Intent请求中没有设定Action类型,那么即使<intent-filter>中包含有Action类型,也无法匹配。
(3) Intent请求和<intent-filter>种都没有Action类型也不会匹配
(4)对于Activities和BroadcastReceiver都遵循(1),(2),(3)

注意1:《unlocking Android》书上的说是错误的。
注意2:总的来说就是至少要有一项匹配。
这个 Intent请求就将顺利地通过<intent-filter>的行为测试。
注:
在intent中可以通过
        Intent(String  action)
Create an intent with a given action.
    Intent(String action, Uri uri)
Create an intent with a given action and for a given data url.
等方式设置
例1
Intent intent=new Intent("com.teleca.action.MAIN");
<intent-filter>
    <action android:name="com.teleca.action.MAIN" />
    <category android:name="android.intent.category.DEFAULT" />

</intent-filter>
2.类别匹配
<intent-filter>元素可以包含<category>子元素,比如:
<intent-filter . . . >
<category android:name=”android.Intent.Category.DEFAULT” />
<category android:name=”android.Intent.Category.BROWSABLE” />

</intent-filter>
只有当Intent请求中所有的Category与组件中某一个IntentFilter的<category>完全匹配时,才会让该 Intent请求通过测试,
IntentFilter中多余的<category>声明并不会导致匹配失败。一个没有指定任何类别测试的 IntentFilter仅仅只会匹配没有设置类别的Intent请求。
(1),所有的Activities通常在IntentFilter支持"android.intent.category.DEFAULT",
    否则在Context.startActivity()中无法找到它.
(2)、对于Activities如果在IntentFilter只支持"android.intent.category.DEFAULT",
    那么在Intent请求中:
    要么不加任何类别;
     要么只加"android.intent.category.DEFAULT"。
(3)对于Activities,如果在IntentFilter支持项不止"android.intent.category.DEFAULT"一项时,
    那么在Intent请求中:
    要么不加任何类别,
    要么只加"android.intent.category.DEFAULT"。
    要么加一个非"
android.intent.category.DEFAULT"项来和IntentFilter中的一项匹配
(4)对于BroadcastReceiver:如果Intent中没有加任何类别,那么它可以和IntentFilter中的任何一项类别匹配。即使IntentFilter没有任何类别,也能匹配通过。
(5)对于BroadcastReceiver,如果IntentFilter没有任何类别,那么Intent中也必须要没有加任何类别,才能通过
    注1:
        在intent中可以通过
         addCategory(String  category)
        Add a new category to the intent.
        等方式设置
例2
        Intent intent=new Intent("com.teleca.action.MAIN");
        intent.addCategory("com.teleca.category.DEFAULT");
       
 startActivity(intent);
        
    <intent-filter>
        <action android:name="com.teleca.action.MAIN"/>
        <category android:name="com.teleca.category.DEFAULT" />
        <category android:name="android.intent.category.DEFAULT" />

    </intent-filter>
3.数据匹配
(1)如果有方案没类型,则任何类型的Intent都匹配。
(2)如果有类型没方案,则任何方案的Intent都匹配。
(3)如果方案和类型都没有,则只有既没方案也没类型的Intent才匹配。
(4)指定了授权,这必须指定方案。
(5)指定了路径,就必须指定方案和授权。
(6)如果指定了方案和授权但没指定路径,那么将匹配任何路径。
(7)如果有方案,那么请求的Intent的方案不能为空,必须要有与之对应的方案。
(8)如果有授权,那么请求的Intent的授权不能为空,必须要有与之对应的授权。
    数据定义主要有两种形式:
    第一种形式是方案+授权+路径的组合。这里的数据类型可以选的.
    如下:
    weather://com.msi.manning/loc?zip=12345
   方案weather
   授权com.msi.manning
   路径loc?zip=12345
    例1:
    <intent-filter >
    <data android:type="video/mpeg" android:scheme=”http” . . . />
    <data android:type="audio/mpeg" android:scheme=”http” . . . />

    </intent-filter>
    <data> 元素指定了希望接受的Intent请求的数据URI,并显式的指定了数据类型,URI被分成三部分来进行匹配:scheme、 authority和path。
    【这里的android:type应该是老的写法,新的应该是android:mimeType】
    其中,用setData()设定的Inteat请求的URI数据类型和scheme必须与IntentFilter中所指 定的一致。
    若IntentFilter中还指定了authority或path,它们也需要相匹配才会通过测试。

    例2
            <intent-filter>
                <action android:name="com.teleca.action.MAIN"/>
                <category android:name="com.teleca.category.DEFAULT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:
scheme="weather" android:host="com.msi.manning"/>
            </intent-filter>
    Intent intent=new Intent("com.teleca.action.MAIN",Uri.parse("weather://com.msi.manning/loc?zip=12345"));
    intent.addCategory("com.teleca.category.DEFAULT");

    startActivity(intent);
    注意1:这里没显式的指定数据类型
    注意1:这里省略了路径,以便匹配任何路径。
第二种是显式MIME形式.
这种Intent主要用于和ContentProvider的交互上。
我们并不直接创建和使用这种类型的Intent,我们只是在ContentProvider的AndroidManifest.xml中,配置ContentProvider的<intent-filter >
关于此的更多内容请参考《ContentProvider》
如下:
    例1
    content://com.google.provider.NotePad/notes
    方案content这种形式表示该数据类型优先于平台的数据类型。[表示是ContentProvier提供的]。[它应该是固定的]
    授权com.google.provider.NotePad
    路径notes
    以上是MIME的形式的数据.
     而下面的则是方案授权,路径的组合
     weather://com.msi.manning/loc?zip=12345
     MIME形式的数据是在定义provider的时候定义的。
     比如:
     <provider android:name="widgetProvider" android:authorities="com.msi.manning.chapter5.Widget">
注意以下是只定义只有data类型的做法:
    <intent-filter>
     <action android:name="android.intent.action.GET_CONTENT" />
     <category android:name="android.intent.category.DEFAULT" />
     
<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
    </intent-filter>
注1
    只定义数据的data类型例子程序测试成功。
    如下:
            Intent intent=new Intent("com.teleca.action.MAIN");
            intent.addCategory("com.teleca.category.DEFAULT");
            
intent.setType("vnd.android.cursor.item/vnd.google.note");
            startActivity(intent);

            <intent-filter>

                <action android:name="com.teleca.action.MAIN"/>
                <category android:name="com.teleca.category.DEFAULT" />
                <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="vnd.android.cursor.item/vnd.google.note"/>
            </intent-filter>
    但是在数据的data类型和方案+授权混合使用的例子程序测试失败。
    如下:
        Intent intent=new Intent("com.teleca.action.MAIN",Uri.parse("weather://com.msi.manning/loc?zip=12345"));
        intent.addCategory("com.teleca.category.DEFAULT");
        intent.setType("vnd.android.cursor.item/vnd.google.note");
        startActivity(intent);

        <intent-filter>

            <action android:name="com.teleca.action.MAIN"/>
            <category android:name="com.teleca.category.DEFAULT" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="vnd.android.cursor.item/vnd.google.note" android:scheme="weather" 
             android:host="com.msi.manning"/>
        </intent-filter>
 注2
    在intent中可以通过
        Intent(String action, Uri uri)
    Create an intent with a given action and for a given data url.
    等方式设置数据元素的uri
 注3:
 在manifest文件中定义type:
 android:type应该是老的写法,新的应该是android:mimeType
 android:type的写法在2.1编译不过。
    在intent中可以通过
     Intent     setType(String  type)
    Set an explicit MIME data type.
    方式设置type元素的值
原创粉丝点击