我们最常使用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. 【C#】使用C# 读取Http的Post数据

    private string Post(string num) { Encoding myEncoding = Encoding.GetEncoding("gb2312"); // ...

  2. ThinkPhp5 数据迁移(think-migration)

    ThinkPhp5 数据迁移(think-migration)   在thinkphp5中提供了数据迁移工具(think-migration),它是机遇phinx开发(文档地址:http://docs ...

  3. 修改TestStand Testsocket 从非0开始

    Issue Details I am running the parallel process model or batch model and want my test sockets to be ...

  4. Mac下 homebrew 安装mysql

    操作步骤 安装homebrew brew install mysql 安装mysql 安装完成之后,可以运行命令启动mysql服务 mysql.server start 然后输入命令设置密码 mysq ...

  5. [ARM-Linux开发]linux dmesg命令参数及用法详解(linux显示开机信息命令)

    功能说明:显示开机信息.语 法:dmesg [-cn][-s <缓冲区大小>]补充说明:kernel会将开机信息存储在ring buffer中.您若是开机时来不及查看信息,可利用dmesg ...

  6. Dede后台验证码不显示解决方法详解(dedecms 5.7 UTF-8版本)

    织梦(dede)后台验证码不显示有多种可能性,我前几天测试就碰到了这个问题,结果百度搜索了一圈,挨个修改了下,还是不行,最后是在解决另外一个后台上传图片不成功的问题的时候,歪打正着的把验证码问题给解决 ...

  7. 1 linux性能优化之平均负载uptime

    不知道onenote的笔记复制出来就是图片了...

  8. Redis Sentinel 高可用部署实践集群

    一.Redis Sentinel 介绍    1.Sentinel     数据库环境搭建,从单机版到主备.再到多数据库集群,我们需要一个高可用的监控:比如Mysql中,我们可能会采用MHA来搭建我们 ...

  9. Opencv颜色识别与追踪

    这是基于颜色识别的物体追踪 不废话 直接看代码 这是Opencv3的代码 //---------------------------------[头文件.命名空间包含部分]-------------- ...

  10. STL源码剖析——序列式容器#3 Deque

    Deque是一种双向开口的连续线性空间.所谓的双向开口,就是能在头尾两端分别做元素的插入和删除,而且是在常数的时间内完成.虽然Vector也可以在首端进行元素的插入和删除(利用insert和erase ...