深入学习Android中的Intent

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

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

Intent又分为隐士意图显示意图

显示意图:调用intent.setComponent()、intent.setClassName()或者intent.setClass()方法明确的制定组件名的Intent为显示意图,显示意图明确的制定要激活哪一个组件。

隐士意图:没有明确的制定组件的名称;下边是一个隐士意图的案例

首先应该在清单文件中添加相应的intent-filter

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
      android:label="@string/app_name"
      android:name=".IntentActivity" >
      <intent-filter >
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>

    <activity android:name=".OtherActivity" android:label="@string/windowtitle">
      <intent-filter >
        <action android:name="cn.itcast.zhangxx"/>
        <action android:name="cn.itcast.laoli"/>
        <category android:name="cn.itcast.category.java"/> 
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="cn.itcast.category.php"/>
        <data android:scheme="itcast" android:host="www.itcast.cn" android:path="/liming"/>
        <data android:mimeType="image/*"/>
      </intent-filter>      
    </activity>
  </application>

在MainActivity.java中

public void openActivity(View v){
    /**
     * (没设数据参数的情况下)只要Intent中的Action和Category都出现在Intent-Filter中,就能与之匹配,否则匹配失败
     */
    Intent intent = new Intent();//隐式意图激活Activity
    intent.setAction("cn.itcast.zhangxx");
    intent.addCategory("cn.itcast.category.java");  

    // intent.setData(Uri.parse("itcast://www.itcast.cn/liming"));
    // intent.setType("image/jpeg");
    //根据Android的API可以知道
    //This method automatically clears any data that was previously set (for example by setData(Uri)). 
    //也就是说如果设置了setData方法在设置setType方法的话,那么setType方法就会clers掉setData方法
    //解决方案如下:

    intent.setDataAndType(Uri.parse("itcast://www.itcast.cn/liming"), "image/jpeg");
    startActivity(intent);//方法内部为Intent添加了android.intent.category.DEFAULT类别
  }

如下是隐士意图的匹配规则:

Intent Filter(意图过滤器)其实就是用来匹配隐式Intent的,当一个意图对象被一个意图过滤器进行匹配测试时,只有三个方面会被参考到:动作、数据(URI以及数据类型)和类别。

动作测试(Action test)

一个意图对象只能指定一个动作名称,而一个过滤器可能列举多个动作名称。如果意图对象或过滤器没有指定任何动作,结果将如下:

  • • 如果过滤器没有指定任何动作,那么将阻塞所有的意图,因此所有的意图都会测试失败。没有意图能够通过这个过滤器。
  • • 另一方面,只要过滤器包含至少一个动作,一个没有指定动作的意图对象自动通过这个测试

类别测试(Category test)

对于一个能够通过类别匹配测试的意图,意图对象中的类别必须匹配过滤器中的类别。这个过滤器可以列举另外的类别,但它不能遗漏在这个意图中的任何类别。

原则上一个没有类别的意图对象应该总能够通过匹配测试,而不管过滤器里有什么。大部分情况下这个是对的。但有一个例外,Android把所有传给startActivity()的隐式意图当作他们包含至少一个类别:”android.intent.category.DEFAULT” (CATEGORY_DEFAULT常量)。因此,想要接收隐式意图的活动必须在它们的意图过滤器中包含”android.intent.category.DEFAULT”。(带”android.intent.action.MAIN”和”android.intent.category.LAUNCHER”设置的过滤器是例外)

数据测试(Data test)

当一个意图对象中的URI被用来和一个过滤器中的URI比较时,比较的是URI的各个组成部分。例如,如果过滤器仅指定了一个scheme,所有该scheme的URIs都能够和这个过滤器相匹配;如果过滤器指定了一个scheme、主机名但没有路经部分,所有具有相同scheme和主机名的URIs都可以和这个过滤器相匹配,而不管它们的路经;如果过滤器指定了一个scheme、主机名和路经,只有具有相同scheme、主机名和路经的URIs才可以和这个过滤器相匹配。当然,一个过滤器中的路径规格可以包含通配符,这样只需要部分匹配即可。

数据测试同时比较意图对象和过滤器中指定的URI和数据类型。

规则如下:

a. 一个既不包含URI也不包含数据类型的意图对象仅在过滤器也同样没有指定任何URIs和数据类型的情况下才能通过测试。

b. 一个包含URI但没有数据类型的意图对象仅在它的URI和一个同样没有指定数据类型的过滤器里的URI匹配时才能通过测试。这通常发生在类似于mailto:和tel:这样的URIs上:它们并不引用实际数据。

c. 一个包含数据类型但不包含URI的意图对象仅在这个过滤器列举了同样的数据类型而且也没有指定一个URI的情况下才能通过测试。

d. 一个同时包含URI和数据类型(或者可从URI推断出数据类型)的意图对象可以通过测试,如果它的类型和过滤器中列举的类型相匹配的话。如果它的URI和这个过滤器中的一个URI相匹配或者它有一个内容content:或者文件file: URI而且这个过滤器没有指定一个URI,那么它也能通过测试。换句话说,一个组件被假定为支持content:和file: 数据如果它的过滤器仅列举了一个数据类型。

以上就是针对Android中的Intent详细介绍,特别适合初学者学习,希望对大家的学习有所帮助。


代码注释

作者:喵哥笔记

IDC笔记

学的不仅是技术,更是梦想!