Android中的Intent和Intent-Filter详解(一)

Intent对于Android应用的作用

Intent,翻译过来是“意图”,它是对Android应用程序“意图”的封装。例如ActivityA想启动ActivityB,那么“想启动ActivityB”就是ActivityA的意图;ActivityA想启动ServiceA,“想启动ServiceA”就是ActivityA的意图。

至于Android为什么不直接提供一个类似startActivity(Class activityClass)的方法来移动一个Activity,是因为这样做会背离Android的设计理念,造成一种硬编码耦合,不利于高层次的解耦。而Intent提供的编程模型,可以让应用程序只启动具有某种特征额组件,不会造成组件(ActivityServiceContentProvider)之间的耦合。

Intent不仅可以封装应用程序需要启动某个组件的“意图”,还可以作为应用组件之间通信的重要媒介。例如两个Activity之间可以通过Bundle对象交换数据,而Intent刚好可以携带Bundle对象。

 

Intent对象如何启动系统组件

Android应用程序包含三种重要组件:ActivityServiceBroadcastReceiver,应用程序采用了一致的方式来启动他们——都是依靠Intent来进行启动的,Intent就封装了程序想要启动程序的意图,不仅如此,Intent还可用于与被启动组件交换信息。

下表显示一部分使用Intent启动不同组件的方法:

组件类型

启动方法

Activity

startActivity(Intent i)

 

startActivityForResult(Intent intent, int requestCode)

Service

ComponentName startService(Intent service)

 

boolean bindService(Intent service, ServiceConnection conn, int flags)

BroadcastReceiver

sendBroadcast(Intent intent)

 

sendBroadcast(Intent intent, String receiverPermission)

 

sendOrderedBroadcast(Intent intent, String receiverPermission)

 

Intent对象大致包含Component, Action, Category, Data, Type, ExtraFlag7中属性,其中Component用于明确指定需要启动的目标组件,而Extra用于携带需要交换的数据。下面详细介绍Intent对象各属性的作用。

 

Intent的属性及Intent-Filter配置

我们知道Intent是用来封装程序的启动意图的,但到底启动哪个组件,则取决于Intent的各个属性。

首先举个例子,有一个女孩儿要找男朋友,此时有两种方式来表达她的意图:

  • 明确指出要找xxx做她的男朋友,比如找博主我^_^

  • 指出要找做男朋友,至于到底是谁不重要,只要是高富帅就行;

 

同样,Intent封装的意图与之类似:

  • 显式Intent:通过Component属性明确指定要启动哪个组件;

  • 隐式Intent:通过ActionCategory属性指出需要启动符合条件的组件;

 

Component属性

该属性用来明确指定需要启动哪个组件,其构造函数如下:

  • ComponentName(Stringpkg, String cls):创建pkg所在包下的cls类所对应的组件;

  • ComponentName(Contextpkg, String cls):创建pkg所对应的包下的cls类所对应的组件;

  • ComponentName(Contextpkg, Class<?> cls):创建pkg所对应的包下的cls类所对应的组件;

下面是例子:

ComponentNamecomponentName =newComponentName(getApplicationContext(),ActivityB.class);
Intent intent =newIntent();
intent.setComponent(intent);
startActivity(intent);

除此之外,Intent也提供了快捷的方法和构造函数:

  • setClass(Contextpkg, Class<?> cls)

  • setClassName(Contextpkg, Class<?> cls)

  • setClassName(Stringpkg, String cls)

  • Intent(Contextcontext, Class<?> cls)

下面是例子:

Intent intent1 = new Intent(getApplicationContext(), ActivityB.class);

startActivity(intent1);

Intent intent2 = new Intent();

intent2.setClass(getApplicationContext(), ActivityB.class);

startActivity(intent2);

ActionCategory属性与Intent-Filter配置

ActionCategory属性值都为字符串,其中Action表示Intent将要完成的一个抽象动作Category用于为Action指定更加详细的类别信息或执行的环境,所以这两个属性一般会结合使用。

先通过一个例子来了解一下:

public class ActivityA extends Activity {

    public static final String ACTION_TEST = "com.gisirfive.ACTION_TEST";

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        Button button = new Button(this);

        button.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                Intent intent = new Intent();

                intent.setAction(ACTION_TEST);

                startActivity(intent);

            }

        });

        setContentView(button);

    }

}

 

<application
      ……
    <activity android:name=".ActivityB">

        <intent-filter>

            <!--指定该Activity能响应Action为指定字符串的Intent-->

            <action android:name="com.gisirfive.ACTION_TEST"/>

        </intent-filter>

    </activity>

</application>

 

该例子是在ActivityA中点击按钮,通过Action指定将要启动的组件。从代码我们可以知道,startActivity()将会启动ActivityB,但是ActivityA并不知道它会启动ActivityB,它只知道它“想要启动Action包含ACTION_TEST的组件,这就是它的意图

使用隐式Intent的好处是避免了硬编码的方式建立组件之间的交互。

上面程序中出现了Intent-Filter,我们知道它是放在组件(Android三个常用组件)里面使用的,通常可以包含如下子元素:

  • 0个或多个<action../>元素

  • 0个或多个<category…/>元素

  • 0个或1<data …/>元素

 

这里需要指出的是,虽然<intent-filter>可以包含多个Action元素,但是一个Intent对象最多只能包含一个Action属性,相当于“意图只能包含一个抽象动作。相反,Intent可以包含多个CategoryIntent默认包含一个Intent.CAETGORY_DEFAULT常量,其值为android.intent.category.DEFAULT),这相当于“意图对这个抽象动作指定特定的执行环境。

 

指定ActionCategory调用系统Activity

Intent不仅可以启动本应用内的程序组件,也可以启动Android系统的其他应用的程序组件,包括系统自带的程序组件——只要权限允许。

Android内部提供了大量标准ActionCategory常量,其中用于启动Activity的标准Action常量及对应的字符串如下:

Action常量

对应字符串

简单说明

ACTION_MAIN

android.intent.action.MAIN

应用程序入口

ACTION_VIEW

android.intent.action.VIEW

显示指定数据

ACTION_ATTACH_DATA

android.intent.action.ATTACH_DATA

指定某块数据将被附加到其他地方

ACTION_EDIT

android.intent.action.EDIT

编辑指定数据

ACTION_PICK

android.intent.action.PICK

从列表中选择某项并返回所选的数据

ACTION_CHOOSER

android.intent.action.CHOOSER

显示一个Activity选择器

ACTION_GET_CONTENT

android.intent.action.GET_CONTENT

让用户选择数据,并返回所选数据

ACTION_DIAL

android.intent.action.DIAL

显示拨号面板

ACTION_CALL

android.intent.action.CALL

直接向指定用户打电话

ACTION_SEND

android.intent.action.SEND

向其他人发送数据

ACTION_SENDTO

android.intent.action.SENDTO

向其他人发送消息

ACTION_ANSWER

android.intent.action.ANSWER

应答电话

ACTION_INSERT

android.intent.action.INSERT

插入数据

ACTION_DELETE

android.intent.action.DELETE

删除数据

ACTION_RUN

android.intent.action.RUN

运行数据

ACTION_SYNC

android.intent.action.SYNC

执行数据同步

ACTION_PICK_ACTIVITY

android.intent.action.PICK_ACTIVITY

用于选择Activity

ACTION_SEARCH

android.intent.action.SEARCH

执行搜索

ACTION_WEB_SEARCH

android.intent.action.WEB_SEARCH

执行Web搜索

ACTION_FACTORY_TEST

android.intent.action.FACTORY_TEST

工厂测试的入口点

 

标准Category常量及对应的字符串如下:

Category常量

对应字符串

简单说明

CATEGORY_DEFAULT

android.intent.category.DEFAULT

默认的Category

CATEGORY_BROWSABLE

android.intent.category.BROWSABLE

指定该Activity能被浏览器安全调用

CATEGORY_TAB

android.intent.category.TAB

指定该Activity作为TabActivityTab

CATEGORY_LAUNCHER

android.intent.category.LAUNCHER

Activity显示顶级程序列表中

CATEGORY_INFO

android.intent.category.INFO

用于提供包信息

CATEGORY_HOME

android.intent.category.HOME

设置该Activity随系统启动而运行

CATEGORY_PREFERENCE

android.intent.category.PREFERENCE

Activity是参数面板

CATEGORY_TEST

android.intent.category.TEST

Activity是一个测试

CATEGORY_CAR_DOCK

android.intent.category.CAR_DOCK

指定手机被插入汽车底座(硬件)时运行该Activity

CATEGORY_DESK_DOCK

android.intent.category.DESK_DOCK

指定手机被插入桌面底座(硬件)时运行该Activity

CATEGORY_CAR_MODE

android.intent.category.CAR_MODE

设置该Activity可在车载环境下使用

 

下面是一个返回桌面的例子:

private void fackBackHome(){

    Intent intent = new Intent();

    intent.setAction(Intent.ACTION_MAIN);

    intent.addCategory(Intent.CATEGORY_HOME);

    startActivity(intent);

}

 

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值