我们最常使用Intent来实现Activity之间的转跳,最近做一个app用到从系统搜索图片的功能,使用到了intent的 setType 方法和 setAction 方法,网上搜索一番,发现实现转跳只是Intent功能的九牛一毛,现在对Intent功能做一个总结,以作备忘。

我们经常使用如下方法实现一个转跳:

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

其实这种写法还可以写作

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

这种启动方式被称之为“显式意图”,因为它直接指定了意图目标

还有一种方式称之为“隐式意图”,我们不直接指定目标组件,而是通过设置Intent的各个属性来启动目标组件

Intent

Intent由 ComponentName 、 Action 、 Data 、 Category 、 Extra 、 Flag 六部分来组成,Intent通过调用 setXXX() 方法来设置其对应的属性,下面详细介绍各个属性

【ComponentName】

ComponentName 用于标识位移的应用程序组件,即指明了期望的Intent,这种对象的名称是由目标组件的包名,与期望的类名组合而成,在Intent传递过程中,组件名称是一个可选项。当指定它时,便是显式的Intent消息;而当不指定它时,Android系统会根据其他信息,以及IntentFilter的过滤条件来选择相应的组件。

【Action】

Action 实际上就是一个描述了Intent所出发动作名称的字符串,在Intent类中,已经定义好很多字符串常量来表示不同的Action,当然开发人员也可以自定义Action

常见的Action常量

ACTION_CALL——播出Data里封装的电话号码

ACTION_EDIT——打开Data里指定数据所对应的编辑程序

ACTION_VIEW——打开能够显示Data之中封装的数据的应用程序

ACTION_MAIN——声明程序入口,该Activity并不会接收任何数据,同时结束后也部会返回任何数据

ACTION_BOOT_COMPLETED——BraodcastReceiver Action常量,表明系统启动完毕

ACTION_TIME_CHANGED——BraodcastReceiver Action常量,表示系统时间通过设置而改变

更多可以查看 http://www.cnblogs.com/xs104/p/5111858.html

因为API的更新,部分名称会改变,但基本思路不变。

【Data】

Data 主要是对Intent消息中数据的封装,主要描述Intent的动作所操作到底数据的URI及类型。不同类型的 Action会有不同的Data封装,例如打电话的Intent会封装tel://格式的电话URI,而ACTION_VIEW的Intent中Data则会封装http://格式的URI,正确的Data封装对Intent匹配请求同样非常重要

【Category】

Category 是对目标组件类别信息的描述,同样为一个字符串对象,一个Intent中可以包含多个Category,与Category相关的方法有三个:

1.添加一个Category——addCategory

2.删除一个Category——removeCategory

3.得到一个Category——getCategory

Android系统同样定义了一组常量来表示Intent的不同类别,一些常见的Category常量

CATEGORY_GADGET,表示目标Activity是可以嵌入到其他Activity中的。

CATEGORY_HOME,表明目标Activity为HOME Activity。

CATEGORY_TAB,表明目标Activity是TabActivity的一个标签下的Activity。

CATEGORY_LAUNCHER,表明目标Activity是应用程序中最先被执行的Activity。

CATEGORY_PREFERNCE,表明目标Activity是一个偏好设置的Activity。

【Extra】

extra 中封装了一些额外附加的信息,这些信息以键值对的形式存在,Intent可以通过putExtras()和getExtras()方法来存储和获取Extra,Android系统同样定义了一些Extra常量

EXTRA_CC,邮件抄送人邮箱地址。

EXTRA_EMAIL,装有邮件发送地址的字符串数组。

EXTRA_SUBJECT,当使用ACTION_SEND动作时,描述要发送邮件的主题。

EXTRA_TEXT,当使用ACTION_SEND动作时,描述要发送文本的信息。

【Flags】

android中Intent的Flags有20多种,如下

FLAG_GRANT_READ_URI_PERMISSION
FLAG_GRANT_WRITE_URI_PERMISSION
FLAG_DEBUG_LOG_RESOLUTION
FLAG_FROM_BACKGROUND
FLAG_ACTIVITY_BROUGHT_TO_FRONT
FLAG_ACTIVITY_CLEAR_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
FLAG_ACTIVITY_FORWARD_RESULT
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
FLAG_ACTIVITY_MULTIPLE_TASK
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_NO_ANIMATION
FLAG_ACTIVITY_NO_HISTORY
FLAG_ACTIVITY_NO_USER_ACTION
FLAG_ACTIVITY_PREVIOUS_IS_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_REORDER_TO_FRONT
FLAG_ACTIVITY_SINGLE_TOP
FLAG_ACTIVITY_TASK_ON_HOME
FLAG_RECEIVER_REGISTERED_ONLY

但是我们常用的只有4种

FLAG_ACTIVITY_CLEAR_TOP

例如现在的栈情况为:A B C D 。D此时通过intent跳转到B,如果这个intent添加FLAG_ACTIVITY_CLEAR_TOP 标记,则栈情况变为:A B。如果没有添加这个标记,则栈情况将会变成:A B C D B。也就是说,如果添加了FLAG_ACTIVITY_CLEAR_TOP 标记,并且目标Activity在栈中已经存在,则将会把位于该目标activity之上的activity从栈中弹出销毁。这跟上面把B的Launch mode设置成singleTask类似。
FLAG_ACTIVITY_NO_HISTORY
例如现在栈情况为:A B C。C通过intent跳转到D,这个intent添加FLAG_ACTIVITY_NO_HISTORY标志,则此时界面显示D的内容,如果此时D中又跳转到E,栈的情况变为:A B C E,此时按返回键会回到C,因为D根本就没有被压入栈中。
FLAG_ACTIVITY_SINGLE_TOP
和上面Activity的 Launch mode的singleTop类似。如果某个intent添加了这个标志,并且这个intent的目标activity就是栈顶的activity,那么 将不会新建一个实例压入栈中。

  

FLAG_ACTIVITY_NEW_TASK
例如现在栈1的情况是:A B C。C通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK 标 记,如果D这个Activity在Manifest.xml中的声明中添加了Task affinity,并且和栈1的affinity不同,系统首先会查找有没有和D的Task affinity相同的task栈存在,如果有存在,将D压入那个栈,如果不存在则会新建一个D的affinity的栈将其压入。如果D的Task affinity默认没有设置,或者和栈1的affinity相同,则会把其压入栈1,变成:A B C D,这样就和不加FLAG_ACTIVITY_NEW_TASK 标记效果是一样的了。 

  注意如果试图从非activity的非正常途径启动一个activity,比如从一个service中启动一个activity,则intent必须要添加 FLAG_ACTIVITY_NEW_TASK  标记。

  更多:Intent中的Flag

IntenFilter

IntentFilter 描述了一个组件愿意接收什么样的Intent对象,Android将其抽象为android.content.IntentFilter类。在 Android 的AndroidManifest.xml 配置文件中可以通过 <intent-filter> 节点,为一个Activity指定其IntentFilter,以便告诉系统该Activity可以响应什么类型的 Intent。这样的Intent称为隐式的Intent。

当程序员使用startActivity(intent)来启动另外一个Activity时,如果直接指定intent了对象的Component属性,那么Activity Manager将试图启动其Component属性指定的Activity。否则Android将通过Intent的其它属性,从安装在系统中的所有Activity中查找与之最匹配的一个启动。如果没有找到合适的Activity,应用程序会得到一个系统抛出的异常。

Intent的匹配

  Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:

  1 如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;

  2 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。

  3 如果Intent中的数据不是content: 类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme (比如 http: 或者mailto:) 进行匹配。

  同上,Intent 的scheme必须出现在目标组件的scheme列表中。

  4 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。

  比如Intent中包含了两个类别:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。每一个通过startActivity()方法发出的隐式Intent都至少有一个category,就是"android.intent.category.DEFAULT",

所以只要是想接收一个隐式Intent的Activity都应该包括"android.intent.category.DEFAULT" category,不然将导致 Intent 匹配失败。

Android笔记(七十四) 详解Intent的更多相关文章

  1. Android笔记-2-TextView的属性详解

    [Android 基础]TextView的属性详解 android:autoLink :设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web / ...

  2. Android笔记二十四.Android基于回调的事件处理机制

        假设说事件监听机制是一种托付式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源和事件监听器是统一的,或者说事件监听器全然消失了,当用户在GUI控件上激发某个事件时,控 ...

  3. Android笔记三十四.Service综合实例二

    综合实例2:client訪问远程Service服务 实现:通过一个button来获取远程Service的状态,并显示在两个文本框中. 思路:如果A应用须要与B应用进行通信,调用B应用中的getName ...

  4. Android笔记(七十六) 点菜DEMO

    一个朋友让看一下他的代码,一个点菜的功能,他和我一样,初学者,代码比我的都混乱,也是醉了,干脆想着自己写个demo给他看,原本想着听简单,半个小时应该就可以搞定,真正写的时候,画了3h+,汗颜... ...

  5. Android笔记(六十四) android中的动画——补间动画(tweened animation)

    补间动画就是只需要定义动画开始和结束的位置,动画中间的变化由系统去补齐. 补间动画由一下四种方式: 1.AplhaAnimation——透明度动画效果 2.ScaleAnimation ——缩放动画效 ...

  6. Android笔记(七十五) Android中的图片压缩

    这几天在做图记的时候遇第一次遇到了OOM,好激动~~ 追究原因,是因为在ListView中加载的图片太大造成的,因为我使用的都是手机相机直接拍摄的照片,图片都比较大,所以在加载的时候会出现内存溢出,那 ...

  7. Android笔记(七十二) Style和Theme

    我们尝尝需要使用setText.setColor.setTextSize等属性来设置控件的样式,但是每个控件都需要设置这些属性,工作量无疑是巨大的,并且后期维护起来也不方便. Style Androi ...

  8. Android笔记(七十) AlertDialog

    alertdialog可以在当前界面中弹出一个对话框,这个对话框在界面所有元素之上,可以屏蔽掉其他控件的交互能力,因此alertdialog常用于一些重要的内容警告. 使用AlertDialog.Bu ...

  9. Android笔记(十四) Android中的基本组件——按钮

    Android中的按钮主要包括Button和ImageButton两种,Button继承自TextView,而ImageButton继承自ImageView.Button生成的按钮上显示文字,而Ima ...

随机推荐

  1. idea 出现 bootstrap.properties 中的内容不能识别

    错误截图如下 依赖库引用问题 第一种: <dependency> <groupId>org.springframework.cloud</groupId> < ...

  2. python之terminaltables

    from terminaltables import AsciiTable, DoubleTable, SingleTable from colorclass import Color, Window ...

  3. 阶段一-01.万丈高楼,地基首要-第3章 用户登录注册模块开发-3-8 优化Swagger2显示

    左侧的全是英文 忽略api 把HelloController也忽略掉 重启api的服务,刷新页面.只剩下了passport的Controller 给passport接口加上注解. 重启服务,并刷新页面 ...

  4. SDN实验---Ryu的应用开发(二)Learning Switch

    一:自学习交换机(二层MAC交换机)的编程思路 (一)明确问题 如何实现软件定义的自学习交换机? (二)设计解决方案 通过控制器来实现自学习交换算法,然后指导数据平面实现交换机操作 (三)确定具体的技 ...

  5. http 1.1 状态码定义

    part of Hypertext Transfer Protocol -- HTTP/1.1RFC 2616 Fielding, et al. 10 Status Code Definitions ...

  6. GhostVLAD for set-based face recognition

    GhostVLAD for set-based face recognition 中提到了文章解决的是template-based face recognition. VLAD: vector of ...

  7. 安装 python 爬虫框架 Scrapy

    官方安装说明文档:https://doc.scrapy.org/en/latest/intro/install.html#installing-scrapy 一.scrapy 需要以下依赖 二.一般来 ...

  8. 大数据 -- kafka学习笔记:知识点整理(部分转载)

    一 为什么需要消息系统 1.解耦 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险.许多 ...

  9. SVN中trunk,branches,tags用法详解[重要]

    Subversion有一个很标准的目录结构,是这样的.比如项目是proj,svn地址为svn://proj/,那么标准的svn布局是 svn://proj/|+-trunk+-branches+-ta ...

  10. 查看表空间使用情况(SQL)

    1: --查询表空间使用情况 2: SELECT Upper(F.TABLESPACE_NAME)         "表空间名", 3:        D.TOT_GROOTTE_ ...