• 详解intent和intentfilter


    1.Intent对象简介

      Intent中文意思指"意图",按照Android的设计理念,Android使用Intent来封装程序的"调用意图",不管启动Activity、Service、BroadcastReceiver,Android都使用统一的Intent对象来封装这一"启动意图"。此外,Intent也是应用程序组件之间通信的重要媒介。

      Android应用程序包含三种重要组件:Activity、Service、BroadcastReceiver,应用程序采用一致的方式启动它们,都是依靠Intent来进行启动的,Intent中封装了程序要启动的意图。

      下面是Intent启动不同组件的部分方法:

      Activity组件:startActivity(Intent intent);startActivityForResult(Intent intent,int requestCode);

      Service组件:startService(Intent intent);bindService(Intent intent,ServiceConnection conn,int flags);

      BroadcastReceiver组件:sendBroadcast(Intent intent);sendOrderedBroadcast(Intent intent,String receiverPermission);

    2.intent的属性及intentfilter的配置

      Intent的属性大致包含:Component,Action,Category,Data,Type,Extra,Flag这7种属性,其中Component用于明确指定需要启动的组件,而Extra则用于"携带"需要交换的数据。

      2.1 Component属性

        Intent的Component属性需要接收一个ComponentName对象,ComponentName构造器包含如下对象:

        1>ComponentName(String pkg,String cls),

        2>ComponentName(Context pkg,String cls),

        3>ComponentName(Context pkg,Class<?> cls)

        创建pkg包下cls类对应的组件,上面的三个构造器本质上就是一个。查看第二个和第三个构造器源代码:

    1   public ComponentName(Context pkg, String cls) {
    2         if (cls == null) throw new NullPointerException("class name is null");
    3         mPackage = pkg.getPackageName();
    4         mClass = cls;
    5     }

        

    1   public ComponentName(Context pkg, Class<?> cls) {
    2         mPackage = pkg.getPackageName();
    3         mClass = cls.getName();
    4     }

        mpackage和mClass分别表示包名和类名,最终都是为了获取包名和类名。注意这块mClass是类的完整名称(包名+类名)

        这说明创建一个ComponentName需要指定包名和类名就可以唯一确定一个组件类。这样,应用程序可以根据给定的组件类启动特定的组件。这里顺便说下Intent包含的三个方法:

        1>setClass(Context context,Class<?> cls)

        2>setClassName(Context context,String className)

        3>setClassName(String packageName,String className)

        这三个方法其实本质上还是调用上面的三个方法,查看第一个源代码:

    1   public Intent setClass(Context packageContext, Class<?> cls) {
    2         mComponent = new ComponentName(packageContext, cls);
    3         return this;
    4     }

        后面两个也是调用不同的ComponentName构造方法,这里就不啰嗦了,自己可以看下源码。

        TIP:

          Android应用的Context代表访问该应用环境信息的接口,Android应用的包名作为应用的唯一标识,因此Android应用的Context对象和包名有一一对应的关系。

        指定Component属性的Intent已经明确它要启动的哪个组件,因此这种Intent也被称为显示"意图".

      2.2 action、category属性与intent-filter配置

        Intent的action、category属性都是普通的字符串,其中action表示Intent需要完成的一个抽象"动作",而category则为action添加额外的类别信息,通常action和category一块使用。

        需要指出的是,一个Intent中只能包含一个action属性,但可以包含多个category属性。当程序创建Intent时,该Intent默认启动常量值为andorid.intent.category.DEFAULT的组件。

        下面写一个Demo,从一个Activity(隐式)启动另一个Activity,布局文件很简单,activity_main添加一个按钮,activity_other显示一行字,这里就不写出了:

        MainActivity类:

     1 package com.example.administrator.intentandintentfilterdemo;
     2 
     3 import android.content.Intent;
     4 import android.os.Bundle;
     5 import android.support.v7.app.ActionBarActivity;
     6 import android.view.View;
     7 
     8 public class MainActivity extends ActionBarActivity {
     9     private static final String FLAG_OTHER = "com.example.administrator.intentandintentfilterdemo.OTHERACTIVITY";
    10     @Override
    11     protected void onCreate(Bundle savedInstanceState) {
    12         super.onCreate(savedInstanceState);
    13         setContentView(R.layout.activity_main);
    14     }
    15 
    16     public void start(View view){
    17         Intent intent = new Intent();
    18         intent.setAction(FLAG_OTHER);
    19         intent.addCategory("android.intent.category.DEFAULT2");
    20         startActivity(intent);
    21     }
    22 
    23 
    24 }
    View Code

        OtherActivity类:

     1 package com.example.administrator.intentandintentfilterdemo;
     2 
     3 import android.app.Activity;
     4 import android.os.Bundle;
     5 
     6 /**
     7  * Created by Administrator on 2015/3/22.
     8  */
     9 public class OtherActivity extends Activity{
    10     @Override
    11     protected void onCreate(Bundle savedInstanceState) {
    12         super.onCreate(savedInstanceState);
    13         setContentView(R.layout.activity_other);
    14     }
    15 }
    View Code

        AndroidManifest.xml:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.example.administrator.intentandintentfilterdemo" >
     4 
     5     <application
     6         android:allowBackup="true"
     7         android:icon="@drawable/ic_launcher"
     8         android:label="@string/app_name"
     9         android:theme="@style/AppTheme" >
    10         <activity
    11             android:name=".MainActivity"
    12             android:label="@string/app_name" >
    13             <intent-filter>
    14                 <action android:name="android.intent.action.MAIN" />
    15 
    16                 <category android:name="android.intent.category.LAUNCHER" />
    17             </intent-filter>
    18         </activity>
    19 
    20         <activity
    21             android:name=".OtherActivity"
    22             android:label="@string/app_name" >
    23             <intent-filter>
    24                 <action android:name="com.example.administrator.intentandintentfilterdemo.OTHERACTIVITY"/>
    25                 <action android:name="com.example.administrator.intentandintentfilterdemo.TEMP"/>
    26                 <category android:name="android.intent.category.DEFAULT2"/>
    27                 <category android:name="android.intent.category.DEFAULT"/>
    28             </intent-filter>
    29         </activity>
    30     </application>
    31 
    32 </manifest>
    View Code

        如果我们不在intent-filter中配置默认category属性,那么就会报异常。从中可以看出只要配置文件中intent-filter包含action、category就可以启动目标组件。切记,在intent-filter中要配置默认的category。

      2.3 data、type属性与intent-filter配置

        Data属性通常用于向action提供操作的数据。一个Data属性接收一个Uri对象,Uri通常通过如下字符串来表示:

        content://com.android.linzi:80/student/1

        Uri总满足如下格式:

        scheme://host:port/path

        上面content是scheme部分,com.android.linzi是host部分,80是prot部分,/student/1是path部分

        Type属性用于指定该Data所指定的MIME类型,这种类型可以是任何自定义的类型,只要符合abc/xyz格式的字符串即可。

        由于Data属性和Type属性关系比较微妙,这两个属性可以相互覆盖,所以希望既有Data属性又有Type属性时应该调用Intent的setDataAndType()方法。

        对上面代码稍作修改

        MainActivity类:

       

    1   public void start(View view){
    2         Intent intent = new Intent();
    3         intent.setAction(FLAG_OTHER);
    4         intent.addCategory("android.intent.category.DEFAULT2");
    5 //        intent.setData(Uri.parse("content://com.example.linzi:80/hanfeng/1"));
    6 //        intent.setType("image/jpg");
    7         intent.setDataAndType(Uri.parse("content://com.example.linzi:80/hanfeng/1"),"image/jpg");
    8         startActivity(intent);
    9     }

        如果将第7行换成5、6行就会报异常,Data和Type会相互覆盖

        AndroidManifest.xml:

        

     1 <activity
     2             android:name=".OtherActivity"
     3             android:label="@string/app_name" >
     4             <intent-filter>
     5                 <action android:name="com.example.administrator.intentandintentfilterdemo.OTHERACTIVITY"/>
     6                 <action android:name="com.example.administrator.intentandintentfilterdemo.TEMP"/>
     7                 <category android:name="android.intent.category.DEFAULT2"/>
     8                 <category android:name="android.intent.category.DEFAULT"/>
     9                 <data
    10                     android:scheme="content"
    11                     android:host="com.example.linzi"
    12                     android:path="/hanfeng/1"
    13                     android:port="80"
    14                     android:mimeType="image/jpg"/>
    15             </intent-filter>
    16         </activity>

      2.4 Extra属性 

        Intent的Extra属性通常用于在多个Activity之间进行数据交换,Extra属性应该是一个Bundle对象,它可以用来存储多组key-value值。

        可以通过putExtra()方法存放数据,putExtra()方法本质上也是通过Bundle来存储数据的,下面是其源码。(这里不做多的介绍,具体请参考前面写的关于Activity的博文)

    1 public Intent putExtra(String name, boolean value) {
    2         if (mExtras == null) {
    3             mExtras = new Bundle();
    4         }
    5         mExtras.putBoolean(name, value);
    6         return this;
    7     }

      2.5 Flag属性

        Intent的Flag属性用于为该Intent添加额外的控制旗标,Intent可调用addFlags()方法为其添加控制旗标

        Android为Intent提供了大量的Flag,每个Flag都有特定的功能,具体请参考Android API文档。

    3.总结:

      在启动Android Activity、Service、BroadcastReceiver等组件时,总需要借助Intent来实现(显示和隐式),Android Intent封装了应用程序的启动意图,但这种意图并未与其它任何组件藕合,这样可以很好的为增强程序的可扩展性和可维护性。应当熟悉component、action、category、data、type各属性的功能和用法。

        

  • 相关阅读:
    HDU1029 Ignatius and the Princess IV
    UVA11039 Building designing【排序】
    UVA11039 Building designing【排序】
    POJ3278 HDU2717 Catch That Cow
    POJ3278 HDU2717 Catch That Cow
    POJ1338 Ugly Numbers(解法二)
    POJ1338 Ugly Numbers(解法二)
    UVA532 Dungeon Master
    UVA532 Dungeon Master
    POJ1915 Knight Moves
  • 原文地址:https://www.cnblogs.com/xsyulinzi/p/4357247.html
Copyright © 2020-2023  润新知