首先什么是Intent呢?
Intent在android中是一个非常非常常用并且重要的类,主要用来在一个组件中启动同一App中的另一个组件或者是启动另一个App中的组件,这里所说的组件指的是Android四大组件其三:Activity(活动)、 Service(服务)以及 Broadcast(广播),,,没有ContentProvider哦。
对这四大组件感兴趣的小伙伴可以进这里了解了解:
Android开发系列——基础篇3:Android四大组件
现在我们聊聊Intent的组成(共6部分)
(Component Name)用于显示Intent
(Action、Data、Category、Extras、Flags)用于隐式Intent
- Component:要启动的组件的名称。如果你想使用显式的Intent,那么你就必须指定该参数,一旦设置了component name,Android会直接将Intent传递给组件名所指定的组件去启动它。
- Action:用特定字符串表示了要执行的操作,比如查看或选择,其对应着Intent Filter中的action标签。一些常见的Action有Intent.ACTION_VIEW、 Intent.ACTION_SECD等等
- Data:指的是Uri对象和数据的MIME类型,其对应着Intent Filter中的data标签。data的类型由Intent的action决定,比如说若action是ACTION_EDIT,那么data的URI应指向一个可编辑的文件。
- Category:是一个字符串,表示目标组件的附加信息,大部分intent不需要category。以下是一些常见的category:
CATEGORY_BROWSABLE 目标组件会允许自己通过一个链接被一个Web浏览器启动,该链接 可能是一个图片链接或e-mail信息等。
CATEGORY_LAUNCHER 用于标识Activity是某个App的入口Activity。 - Extras:一些intent可以携带的附加信息,以键值对的形式存储。可以使用putExtra()方法将键值对信息传入。
- Flags:可以指导系统以何种方式启动一个activity、是否将启动的activity放在该应用的任务栈中等等。
接下来我们来看看怎么用Itent
第一、我们要知道Itent有哪两种类型:
- 显示Itent:(通俗的说就是你必须指名道姓的调用一些组件)
通过指定具体类名启动一个组件。显式Intent一般用于同一应用程序内,因为您可以确定地知道要启动的组件名。另外,Android 5.0以后规定必须显式启动Service。
示例代码:
//这里就显示指定了要启动的组件——ActivityB
Intent intent = new Intent(this, ActivityB.class);
startActivity(intent);
- 隐式Itent:(也就是符合条件的组件会自动冒出供你选择)
当希望启动具备某种特性的组件时,可以使用隐式Intent,隐式Intent无需指定类名,通常用于启动其他应用程序的组件,比如您打算启动一个相机的activity。
当您隐式地启动一个service或activity时,Intent会根据其中的内容,匹配其他组件中manifest文件的Intent-filter,启动符合条件的组件,并把Intent中的参数传过去,如果有多个intent-filter满足条件,那么系统会弹出一个对话框,由用户决定启动哪个组件。
示例代码:
Intent intent = new Intent();
//当你有一些信息想让通过其他Activity展示给用户的时候就设为ACTION_VIEW
intent.setAction(Intent.ACTION_VIEW);
//data的类型由Intent的action决定,
//action是ACTION_VIEW,data是http:开头的URI,则应该是显示或者下载该uri的内容。
intent.setData(Uri.parse(url));
//启动符合条件组件
startActivity(intent);
But !!!
需要注意的是,为了确保App的安全性,我们应该总是使用显式Intent去启动Service并且不要为该Service设置任何的Intent Filter。通过隐式的Intent启动Service是有风险的,因为你不确定最终哪个App中的哪个Service会启动起来以响应你的隐式Intent,更悲催的是,由于Service没有UI的在后台运行,所以用户也不知道哪个Service运行了。
第二、为了支持隐式Intent,我们还需要知道Intent filter
由名字我们就可以知道这是一个关于Intent的过滤器,只有经过它筛选的组件才能被调用。
我们先看看代码
:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
...
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
/**
* @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
* public static final String ACTION_MAIN = "android.intent.action.MAIN";
* @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
* public static final String ACTION_VIEW = "android.intent.action.VIEW";
*
* action为 “android.intent.action.MAIN”表示该Activity是应用的主入口,
* 且无需配置data。
*
* category为 “android.intent.category.LAUNCHER”表示该activity的启动图标(通过icon
* 属性配置)应添加到系统的launcher中,若未配置icon,则会使用application标签下的icon。
*/
上面我们看到了比较常见的两种测试action测试和category测试:
-
action测试
要想通过测试,intent中的action名称要匹配其中之一。
如果intent filter中不包含action列表,而intent指定action,那么intent没有匹配的action,不通过;intent未指定action,而intent filter指定,会自动通过测试。 -
category测试
intent想通过测试,必须匹配全部intent filter中的category。
intent中的定义的每一个category都需要匹配上intent-filter中的category标签,反之不成立(intent-filter中的category标签可能比intent中的定义的category多)。所以无论intent-filter中是否定义了category标签,未添加category的intent总能匹配上该intent-filter。
请注意:通过startActivity()或startActivityForResult()方法隐式启动的intent中,将自动被添加一个CATEGORY_DEFAULT的category,所以若您希望自己的activity能够被隐式启动,则需要在intent-filter中添加一个android.intent.category.DEFAULT的category标签。——该片段摘自Android:Intent全面解析
结尾
好啦,到这里你对Intent应该已经有了一个大概的了解了,若是感兴趣想要深入学习Intent的话请移步到Android官方文档——Intent 和 Intent 过滤器