请原谅我用这么文艺的标题来阐释一颗无时无刻奔腾着的2B青年的心。可是今天要介绍的Intent绝不2B,甚至在我看来,或许还有些许飘逸的味道,至于飘逸在哪里呢?那我们就好好来剖析剖析Intent和它的好搭档IntentFilter的基友情。

开场告白

  Intent在Android大家庭中是一个活泼的小男孩,从小就是交际草。在代码中,Activity、Service、BroadcastReceiver这三个重要的大妈级重量组件,之间的调用关联都是依靠Intent去交流的,例如Activity的startActivity(),Service的startService()、bindService(),BroadcastReceiver的sendBroadcast()、sendOrderBroadcast()等,其中都是需要携带一个Intent(或IntentFilter)的参数。

  当然Intent中要指定要启动组件的信息,或明显活隐晦。明显的就是显式启动:举个例子来说就是Intent你去把这东西交给某某(名字)Activity大妈。隐晦的是隐式启动:当然得不免俗得给例子就是Intent你把这个东东交给昨晚和我一起在菜市场跳广场舞的那个胖大妈,其中广场舞和胖就把某大妈给赤果果的定位了。这就是Intent的两种匹配方式,我都觉得我自己说的怪抽象的了。

  接下来就是介绍IntentFilter的好时机了,它就是大妈的儿子(组件的拦截器)。当如果Intent隐式启动时,Intent会找他的一群小伙伴IntentFilter来,然后问他们说,你们谁的妈昨晚去菜市场跳广场舞了?你们谁的妈又好胖好胖的?然后IntentFilter各想各妈,哎呀,其中一个IntentFilter拍拍脑袋说,这不就是我妈吗!然后他就屁颠屁颠的领着Intent去找某Activity妈把东东交给她了。

  为了避免大家看不懂上面的例子,我还是发扬一下2B青年的社会责任感,用比较教条的语言来介绍一下Intent和IntentFilter:Intent是一个意图对象,组件可以通过设定Intent来启动另外一个组件,有显式启动和隐式启动两种方法,显式启动直接指定要启动的组件的名字,隐式启动则指定action、category、data等来启动符合条件的组件;其中的IntnetFilter就是一个意图过滤器,它会设定一些过滤规则如action、category、data等,如果Intent中的action、category、data与过滤器中相匹配,则为启动该过滤器的组件。

码点代码

  攻城狮的思维就是不见代码不给赞,所以我还是得老老实实得码几个代码出来撑撑场子。但是Intent的显式启动和隐式启动代码度娘一下几大页,在这里再贴上来就对不起人民群众了。所以呢,我就记录点关键代码,如果后面犯失忆了也可以回来侦查一下容易忘的知识。

显式启动Activity、Service:

Intent intent1 = new Intent(getApplicationContext(), MyActivity.class);
startActivity(intent1);//启动Activity组件
startActivityForResult(intent1, 1);//启动有返回的Activity
Intent intent2 = new Intent(getApplicationContext(), MyService.class);
startService(intent2);//启动Service
bindService(intent2, conn, 1);//绑定Service

隐式启动Activity、Service:

Intent intent1 = new Intent();
intent1.setAction("com.net168.test.action.myactivity");
startActivity(intent1);//启动Activity组件
Intent intent2 = new Intent(); intent1.setAction("com.net168.test.action.myservice");
startService(intent2);//启动Service
bindService(intent2, conn, 1);//绑定Service

发送广播:

Intent intent = new Intent();
intent.setAction("com.net168.test.action.mybroadcast");
sendBroadcast(intent);//发送普通广播
sendOrderedBroadcast(intent, null);//发送有序广播

其实很简单,简单得我这的不好意思介绍了。。。

Intent的家世于IntentFilter的纠结

  Intent的背景很复杂,复杂到比一些不入流的HEI社会还复杂些。大体来说,Intent大致包含了Component、Action、Categroy、Data、Type、Extra和Flag这七大金刚(属性),后面我们就好好解释这些大哥大姐们。

Component:它需要接受一个ComponentName的对象,创建一个ComponentName需要指定包名和类名--这就唯一确定了一个组件类,这样程序就可以通过给定的组件类去启动相应的组件;所以我们可以从这里重新给显式启动和隐式启动分个类,一般如果明确指定ComponentName时就是显式启动,反之就是隐式启动。另外我们可以直接在实例化Intent时在构造函数中传入上下文和类名也可以直接帮我们设定了ComponentName,如Intent(this,MyActivity.class),推荐这种方式,比较简洁。

Action:Action要完成一个抽象的动作,但具体由哪个组件来完成则不确定,需要根据IntentFilter来确定组件;在Intent中,Action最多只能有1个,而在IntentFilter中Action可以有多个。这是隐式启动一个组件最基础的属性。

Category:它为Action增加额外的类别信息,因为Action可以启动到多个组件,但是如果往下更详细的分析要启动的组件,可以通过Category来进行拦截;在IntentFilter和Intent中Category可以有多个。任何一个IntentFilter的默认存在一个Intent.CATEGORY_DEFAULT的属性。

Data、Type:这两个算是比较亲的属性。

  Data属性通常用于向Action提供操作的数据,其值为一个Uri对象,Uri对象满足 scheme://host:port/path 的格式,如 content://com.android.contacts/contacts/1,其中content是scheme的部分、com.android.contacts是host的部分、port部分被省略、contacts/1是path的部分。

  Type属性用于指定该Data所指定Uri对应的MIME类型,可以是所以自定义的类型,只要符合abc/xyz格子的字符串即可。

在使用中,我们要知道这两个属性会相互覆盖:如果Intent先设置Data属性,后设置的Type属性将会把Data属性覆盖掉,反之同理。所以如果要设置Data和Type属性的话需要调用Intent的setDataAndType()的方法。

Extra:Extra是用于多量的数据交换,它的对象是一个Bundle对象。

Flag:Flag属性是为了该Intent添加一些额外的控制旗标,可以通过addFlag()添加控制旗标,通常可以通过它来控制Activity的启动效果和启动方式。

这七个属性中,Intent与IntnetFilter匹配的匹配规则在在于Action、Category、data、Type这几个属性中,具体规则如下:

Action的匹配规则:

1、如果Intent中包含action_A,而在IntentFilter中只要存在action_A这个字符串,无论是否还有其他的action_B、action_C,这个Intent都能被IntnetFilter成功匹配。

2、如果如果Intent中包含action_A,只要IntnetFilter中不存在action_A的话,IntentFilter就不能匹配到Intnet。

3、如果Intent中不存在任何action_x,只要IntnetFilter中存在任意一个action_x的话,Filter就能匹配上Intent。

4、如果IntentFilter不存在任何action_x,则无论Intent中无论存在任何action_x或者没有任何action_x的话,两者是完全不能匹配上的。

Category的匹配规则:

  这个匹配关系较为简单,只要Intent中所有category在IntentFilter中都存在,则Intent可以匹配上IntnetFilter,不论此时Intentfilter中还存在其它的category。举个例子,如果Intent中存在category_A、category_B,而Intentfilter中存在category_A、category_B、category_C,则可以匹配;如果而Intentfilter中存在category_A、category_D、category_C,因为Intentf中不存在Intent中存在的category_B,所以匹配失败。

Data和Type的匹配规则:

data由URI来描述和定位,URI由三部分组成,scheme://host:port/path  模式://主机:端口/路径

此外在事件中,还可以设置data的MIME类型,作为事件的datatype属性。

首先明确一个匹配原则,就是对于URI的匹配,只比较IntentFilter中声明的部分。

部分匹配原则:只要IntentFilter中声明的部分匹配成功,就认为整个URI匹配成功。

举例来说,     content://com.silenceburn.SdCardTester:1000/mydata/private/

和IntentFilter定义为  content://com.silenceburn.SdCardTester:1000/     是可以匹配的。

注意IntentFilter中并没有定义path部分,但是依然可以匹配成功,因为IntentFilter不声明的部分不进行比较。

换句话讲,任何符合content://com.silenceburn.SdCardTester:1000/的事件,无论path是什么,都可以匹配成功。

接下来是真正的data部分的,也就是URI的匹配规则如下:

1. 如果data的URI和datatype为空,则 filter 的URI和type也必须为空,才能匹配成功

2. 如果data的URI不为空,但是datatype为空,则 filter 必须定义URI并匹配成功,且type为空,才能匹配成功

3. 如果data的URI为空,但是datatype不为空,则 filter 必须URI为空,定义type并匹配成功,才能匹配成功

4. 如果data的URI和data都不为空,则 filter 的URI和type都必须定义并匹配成功,才能匹配成功。对于URI部分,有一个特殊处理,就是即使IntentFilter没有定义URI,content和file两种URI也作为既存的URI存在。

作者:enjoy风铃
出处:http://www.cnblogs.com/net168/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则下次不给你转载了。

Intent的那些事儿的更多相关文章

  1. Intent相关

    Intent是什么? 翻译为:意图,目的(名词) 其实根本没必要管它是什么,看看它能做什么就好了. 不过后来我知道了,它就是个机制----通信机制-----android的许多组件间的交流要依赖它. ...

  2. 如何自定义Intent.createChooser的显示结果

    Intent是android核心的概念之一,Intent为android系统提供了真正的开放.android的姿态是开放了,但却没有做到位. 拿“发邮件”这一功能来说,为了使用Intent机制来发送邮 ...

  3. 关于android4.3 bluetooth4.0的那些事儿

    马年伊始,刚刚上班的一个星期,公司里没什么事儿可做,只是听说马上可能要做蓝牙的项目.之前也做过关于软硬件通讯之类的项目:android 串口通讯,android usb 转串口通讯. 可是蓝牙这块还真 ...

  4. 说说Makefile那些事儿

    说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...

  5. 总结iOS开发中的断点续传那些事儿

    前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...

  6. setTimeout那些事儿

    一.setTimeout那些事儿之单线程 一直以来,大家都在说Javascript是单线程,浏览器无论在什么时候,都且只有一个线程在运行JavaScript程序. 但是,不知道大家有疑问没——就是我们 ...

  7. Javascript中关于cookie的那些事儿

    Javascript-cookie 什么是cookie? 指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密).简单点来说就是:浏览器缓存. cookie由什 ...

  8. Parcelable序列化的使用,关于intent.getParcelableArrayExtra的使用

    Parcelable相较于Serializable的效率更高 public class ChargeMode implements Parcelable{ public String name; pu ...

  9. android Intent介绍

    Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 ...

随机推荐

  1. 上传文件夹+php

    最近公司做工程项目,实现文件夹上传 网上找了很久,发现网上很多代码大都存在很多问题,不过还是让我找到了一个符合要求的项目. 对项目的文件夹上传功能做出分析,找出文件夹上传的原理,对文件夹的传输模式深入 ...

  2. 手机开发-IOS

    IOS 语言.Object-C,苹果公司收购的语言,专用于IOS开发,是C语言的超集,面向对象的. 开发环境.一是XCode,是苹果的IDE,提供了控件.二是Instruments,测试性能用,收集显 ...

  3. day26(分页查询)

    分页查询思路 问题: 服务器向浏览器想用数据很多的时候可以对数据进行封装. domain层  封装数据 package com.baidu.domain; import java.util.List; ...

  4. Qt_模块简介

    Qt4 和 Qt5最大的区别之一就是底层架构有了修改.Qt5引入了模块化的概念,讲众多功能细分到几个模块之中.需要达到,用什么模块知道到哪个模块去寻找. Qt5模块分为Essentials Modul ...

  5. html5+javascript的管廊监控页面

    这周二做的,支持苹果手机,安卓手机,电脑,平板访问

  6. poj 3258 3273

    poj3258 题目  (最大化最小值)(最小值最大化) 题意:牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离,现在去掉M块石头,要求去掉M块石 ...

  7. codeforces 982 c

    给你一棵树 让你进行切割 问你最多能切多少刀   使得每个连通分量size都是偶数 思路:首先  要是有奇数个节点的话   那么不管你怎么切割  都会有一个连通分量的size是奇数 所以只有偶数的情况 ...

  8. js-图片时间(倒计时)

    <!DOCTYPE html><html>    <head>        <meta charset="UTF-8">      ...

  9. [mysqli_escape]mysql转义两次

    // mysqli_real_escape_string // 第一次转义的结果 SELECT * FROM example WHERE f_email='example@exampl.com' an ...

  10. 开发 C# OPC 客户端

    编写 opc 客户端的思路 1. 使用OPC Client浏览服务器, 查看测试代码修改后的结果. 2. 根据OPC Client搜集到的服务器信息编写代码和服务器交互 3. OPC Client 操 ...