Intent与IntentFilter——属性介绍与显式与隐式Intent

来源:互联网 发布:timcat如何绑定域名 编辑:程序博客网 时间:2024/05/17 23:32

Intent对象简述

Android的应用程序包含三种重要的组件,Activity,Service,BroadcastReceiver,应用程序曹勇了Intent来启动他们,Intent封装了程序想要启动程序的意图,不仅如此,Intent还可用于与启动组件交换信息。

使用Intent启动不同组件的方法:

  • 要激活一个新的Activity,或者让一个现有的Activity做新的操作,可以通过调用Context.startActivity()或者Activity.startActivityForResult()方法。
  • 要启动一个新的Service,或者向一个已有的Service传递新的指令,调用Context.startService()方法或者调用Context.bindService()方法将调用此方法的上下文对象与Service绑定。
  • Context.sendBroadcast()、Context.sendOrderBroadcast()、Context.sendStickBroadcast()这三个方法可以发送Broadcast Intent。发送之后,所有已注册的并且拥有与之相匹配IntentFilter的BroadcastReceiver就会被激活。

Intent的属性:

Component属性

Intent的Component属性需要接受一个ComponentName对象,ComponentName对象包含以下三个构造器。

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

几个构造器的本质是相同的,都是创建pkg所在包下的cls类所对应的组件,这说明创建一个ComponentName需要指定的包名和类名就可以唯一的确定一个组件类,这样应用程序就可以根据给定的组件类去启动特定的组件。
注意:此处不要认为第一个参数是调用方,第二个参数是被调用方。
第一个参数是为了获取被调用方所在的包名。平时写程序的时候由于很多时候都在一个包内,所以这样不会出现错误。一旦被调用方和调用方不再一个包内就会出现问题

除此之外,Intent还包含如下三个方法。

//设置该Intent将要启动的组件对应的类。setClass(Content packageContext, Class<?> cls)//设置该Intent将要启动的组件对应的类名。 setClassName(Context packageContext, String className)//设置该Intent将要启动的组件对应的类名。setClassName(Cintext packageContext, String className)

指定Component的属性已经明确了它将要启动哪个组件,因此这种方式被称为显示Intent,没有指定Component属性的Intent被称为隐式Intent。

Action,Category属性及intent-filter

Intent的Action、Category属性的值都是一个普通的字符串、其中Action代表该Intent所要完成的一个抽象的动作,而Category则用于为Action增加额外的附加类别信息。通常Action属性会与Category属性结合使用。
PS:一个Intent对象最多只能包括一个Action属性,程序可调用Intent的setAction(String str)方法来设置Action的属性值。但一个Intent可以有多个Category,程序可调用Intent的addCategory(String str)方法来为Category属性。

Action和Category常用常量表如下:
这里写图片描述
这里写图片描述

Data、Type属性

Data是需要操作的数据的URI和它的MIME类型。例如,如果action为ACTION_EDIT,那么Data将包含待编辑的数据URI。如果action为ACTION_VIEW, 则Data为http:网络地址的URI。

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.baidu.com"));startActivity(intent);

这里我们首先指定了 Intent 的 action 是 Intent.ACTION_VIEW,这是一个 Android 系统内
置的动作,其常量值为 android.intent.action.VIEW。然后通过 Uri.parse()方法,将一个网址字
符串解析成一个 Uri 对象,再调用 Intent的 setData()方法将这个 Uri 对象传递进去。

与此对应,我们还可以在<intent-filter>标签中再配置一个<data>标签,用于更精确地指
定当前活动能够响应什么类型的数据。<data>标签中主要可以配置以下内容。
1. android:scheme
用于指定数据的协议部分,如上例中的 http 部分。
2. android:host
用于指定数据的主机名部分,如上例中的 www.baidu.com部分 。
3. android:port
用于指定数据的端口部分,一般紧随在主机名之后如 www.baidu.com:80 。
4. android:path
用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
5. android:mimeType
用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

在隐式Intent中,只有<data>标签中指定的内容和 Intent 中携带的 Data完全一致时,当前活动才能够响应
该 Intent。不过一般在<data>标签中都不会指定过多的内容,如上面浏览器示例中,其实只
需要指定 android:scheme 为 http,就可以响应所有的 http 协议的 Intent 了。

Type属性用于指定该Data属性所指定URI对应的MIME类型,这种MIME类型可以是任何自定义的MIME类型,只要符合abc/xyz格式的字符串即可。
PS:通常来说,当Intent不指定Data属性时Type属性才会起作用,否则Android系统将会根据Data属性值来分析数据的类型,所以一般无需指定Type属性。

Extra属性

Intent中提供了一系列 putExtra()方法的重载,可以把我们想要传递的数据暂存在 Intent 中,启动了另一个活动后,只需要把这些数据再从Intent 中取出就可以了。
比如说 FirstActivity 中有一个字符串,现在想把这个字符串传递到SecondActivity 中,你就可以这样编写:

button1.setOnClickListener(new OnClickListener() {    @Override    public void onClick(View v) {        String data = "Hello SecondActivity";        Intent intent = new Intent(FirstActivity.this, SecondActivity.class);        intent.putExtra("extra_data", data);        startActivity(intent);    }});

然后我们在 SecondActivity 中将传递的数据取出,并打印出来,代码如下所示:

public class SecondActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.second_layout);        Intent intent = getIntent();        String data = intent.getStringExtra("extra_data");        Log.d("SecondActivity", data);}}

首先可以通过 getIntent()方法获取到用于启动 SecondActivity 的 Intent,然后调用
getStringExtra()方法,传入相应的键值,就可以得到传递的数据了。这里由于我们传递的是
字符串,所以使用 getStringExtra()方法来获取传递的数据,如果传递的是整型数据,则使用
getIntExtra()方法,传递的是布尔型数据,则使用 getBooleanExtra()方法,以此类推。

PS: 这里putExtra也可以是一个Bundle对象

FLAG属性

在Activity跳转时,可以用FLAG来设置创建Activity的方式。(具体请参考Activity的task机制)
利用addFlag()方法添加flag。
下面给出常用的FLAG:

  1. FLAG_ACTIVITY_NEW_TASK:默认的启动flag,该flag控制重新创建一个新的Activity。
  2. FLAG_ACTIVITY_NO_ANIMATION:该flag控制启动Activity时不使用过度动画。
  3. FLAG_ACTIVITY_NO_HISTORY:该flag控制被顶的Activity将不会保留在Activity栈中。
  4. FLAG_ACTIVITY_REORDER_TO_FRONT:该flag控制如果当前已有Activity,则直接将该Activity带到前台。例如:现在Activity栈中有A、B、C、D、四个Activity,如果使用此flag来启动B,那么启动后的Activity栈中为A、C、D、B。
  5. FLAG_ACTIVITY_SINGLE_TOP:该flag相当于加载模式中的singleTop模式。
  6. FLAG_ACTIVITY_BROUGHT_TO_FRONT:如果通过该flag启动的Activity已经存在,下次在启动时,将知识把该Activity带到前台。
  7. FLAG_ACTIVITY_CLEAR_TOP:相当于加载模式中的singleTask,通过这种flag启动的Activity将把要启动的Activity之上的栈全部弹出。

显式Intent和隐式Intent

现在理解Intent就很简单了,通过指定Component属性来指定被调用方就是显式,通过Action和Category的方式就是隐式。
(我把它理解成显式Intent就是指定这个东西来做,隐式Intent就是含有这个标签的东西来做)

显式Intent

显式Intent很简单,代码如下:

        //创建一个ComponentName对象        ComponentName componentName = new ComponentName(MainActivity.this,        SecondActivity.class);        Intent intent = new Intent();        //设置Component属性        intent.setComponent(componentName);        startActivity(intent);

但是我们不需要这么写,因为Intent的构造方法可以直接设置Component属性。也就是我们常用的方式,代码如下:

        Intent intent = new Intent(MainActivity.this,                SecondActivity.class);        startActivity(intent);

隐式Intent

隐式Intent现在也不难理解了吧,我们只需要设置Action和Category(设置标签),之后在AndroidManifest找到含有这些标签的组件去启动它。

创建一个button,button的点击事件代码如下:

Intent intent = new Intent("com.example.activitytest.ACTION_START");startActivity(intent);

之后我们创建一个SecondActivity继承自Activity类

public class SecondActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //second_layout自己随便写点东西        setContentView(R.layout.second_layout);    }}

最后配置AndroidManifest.xml
<application> 添加

<activity android:name=".SecondActivity" ><intent-filter><action android:name="com.example.activitytest.ACTION_START" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity>

PS:
1. android.intent.category.DEFAULT 是一种默认的 category,在调用startActivity()方法的时候会自动将这个 category 添加到 Intent 中。
2. 如果在AndroidManifest中没有找到符合我们设置的action和Category程序会报错。(AndroidManifest中的标签只能多不能少)

参考书籍博客

《第一行代码》
《Android疯狂讲义》第三版
Category、Data、Type属性与intent-filter配置
基础总结篇之三:Activity的task相关
博客内容是我阅读以上资料加上自己的理解所得,有部分摘抄自以上资料,侵删。

1 0
原创粉丝点击