Activity详解(二)

本篇主要介绍内容;
Intent详解;
Intent filter匹配规则;

一、Intent详解

Intent:在Android中是一个非常重要的类,连接四大组件,主要用来启动Activity、Service和发送广播;

Intent类别:

1、显式Intent
2、隐式Intent

Intent的组成:

1、component(组件):目的组件
2、action(动作):用来表现意图的行动
3、category(类别):用来表现动作的类别
4、data(数据):表示与动作要操纵的数据
5、type(数据类型):对于data范例的描写
6、extras(扩展信息):扩展信息
7、Flags(标志位):期望这个意图的运行模式

1、ComponentName

要启动的组件名称;如果你想使用显式的Intent,那么你就必须指定该参数,一旦设置了component name,Android会直接将Intent传递给组件名所指定的组件去启动它。如果没有设置component name,那么该Intent就是隐式的,Android系统会根据其他的Intent的信息(例如下面要介绍到的action、data、category等)做一些比较判断决定最终要启动哪个组件。
注意:当启动Service的时候,你应该总是指定Component Name。否则,你不确定最终哪个App的哪个组件被启动了,并且用户也看不到哪个Service启动了。
示例:
Intent intent = new Intent();
//参数1:包名 参数2:完整的类名
ComponentName componentName =
new ComponentName("test.jiao.com","test.jiao.com.activity_test.SecondActivity");
intent.setComponent(componentName);
startActivity(intent);
这种方式亦可启动不同应用的Activity;

2、Action

Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件;
可以在Activity的中定一个或多个action来描述Activity要响应的动作;
其对应着Intent Filter中的action标签




我们亦可在启动Activity的时候设定自己想要的动作;
intent.setAction("test.jiao.com.action1");

3、category

category和action有点类似,也是用户定义的字符串;同时系统有很多预定义的category;
常见的有:


category并不是很常用,但是如果一个Activity在定义的时候想要被隐式启动就一定要添加

因为系统在startActivity的时候默认为Intent添加了

4、data

在启动Activity的时候通过Intent携带的数据,其对应着Intent Filter中的data标签
data有两部分组成:mimeType和URI
mimeType是指媒体类型比如:image/jpeg、video/等,可以表示文本、图片等不同的媒体格式;
URI:://:/
Scheme:URI的模式比如http、file等;
Host:URI的主机名,比如www.baidu.com
Port:URI的端口号,比如80
Path:路径信息,可以包含通配符

接下来我们举个例子在Activity中定义:

android:mimeType="video/mpeg"
android:scheme="http" />

如果我們想要匹配该Activity需要
intent.setDataAndType(Uri.parse("http://abc"),"video/mpeg");

5、Type

Type属性用于明确指定Data属性的数据类型;
如上面例子中提到的: android:mimeType="video/mpeg" ,
android:mimeType="image/*" 等

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri data = Uri.parse("file:///storage/sdcard0/平凡之路.mp3");
intent.setDataAndType(data, "audio/mp3");
startActivity(intent);

6、extras

扩展信息、附加信息,是其它所有附加信息的集合。
使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、
正文等保存在extras里,传给电子邮件发送组件。如下:

String[] tos = { "[email protected]" }; //所有收件人
String[] ccs = { "[email protected]" }; //所有抄送
intent.putExtra(Intent.EXTRA_EMAIL, tos);
intent.putExtra(Intent.EXTRA_CC, ccs);
intent.putExtra(Intent.EXTRA_TEXT, "the email text"); //设置附加信息 邮件正文
intent.putExtra(Intent.EXTRA_SUBJECT, "subject"); //设置附加信息 邮件标题
intent.setType("text/plain");
Intent.createChooser(intent, "Choose Email Client");

7、Flags

标志位,期望这个Intent的运行模式,这个在上篇中有详细的解释;

二、Intent filter匹配规则

上面讲到的Intent的可以携带的参数,根据这些参数我们就可以启动我们想要启动的页面;
然而系统是如何根据Intent的参数来匹配要启动的Activity呢?

1、action匹配规则

①如果Intent中的action(仅一个)和Intent filter中的任何一个action匹配成功
(这里的匹配成功是指值完全一样)就算通过验证;




intent.setAction("test.jiao.com.action1");
验证通过

②如果Intent未指定action 而Intent filter中有action过滤,那么该Intent将不能通过验证;




而intent未指定action 将不能与上面的Intent filter匹配成功;

③如果Intent中携带多个action,那么Intent filter中必须包含该Intent中的所有action才能通过验证;



intent.setAction("test.jiao.com.action1");
intent.setAction("test.jiao.com.action2");
intent.setAction("test.jiao.com.action3");

验证不通过;

2、category匹配规则

category的匹配规则和action的规则①③完全一致
唯一不同的是:
如果intent未指定category 而intent filter指定了多个category 该intent将能通过验证,
原因是在startActivity的时候系统默认为intent添加了一个

这里要说明一点:如果Activity要想被隐式启动就必须在Intent filter中添加

为什么上面已经讲过了;

3、data匹配规则

data的匹配规则与action完全一致,它也要求intent中必须含有data数据,并且data数据能够完全匹配过滤规则中
的某一个就算通过验证;举例说明


这种规则制定媒体类型为所有类型的图片,那么intent中的mimeType属性必须为"image/*"才能匹配;
注意:以上过滤规则中虽然并没有指定URI但是却有默认值URI默认值为content和file;
也就是说虽然没有指定URI但是intent中的URI部分必须为content或file才能通过验证;

intent.setDataAndType(Uri.parse("file://abc"),"image/png");

该intent既能通过验证;
如果intent filter中有两组data规则,我们只需匹配一组即可通过验证;

最后:如果我们在启动一个Activity的时候,系统没有找到该Activity会报异常android.content.ActivityNotFoundException,因此如果我们隐式启动一个Activity的时候,我们并不能确定一定有Activity能匹配我们的规则启动成功,可以用PackageManager的resolveActivity或者Intent的resolveActivity方法来判断一下,如果他们找不到相应的Activity就会返回null,从而避免以上错误的出现;
另外:PackageManager的queryIntentActivitys方法可以返回所有可以成功匹配的Activity信息;

你可能感兴趣的:(Activity详解(二))