Android的Intent机制

Intent对象的作用和构成

android意图机制最核心的设计思想,就是引入了组件管理服务作为连接组件的管理者。 该服务的作用:

  • 通过组件的配置信息了解系统中每个组件的类别和功能
  • 帮助调用组件寻找符合其需求的实现组件,将调用者与实现在彻底解耦

在整个意图机制下,有三方角色参与组件间的连接和通信

【调用组件】连接请求的发起者,它期望寻找其他组件来帮助完成所需的功能。通过调用startActivity和bindService等函数发起对目标组件的连接请求

【实现组件】响应调用者请求完成所需任务的组件,每个组件都可以作为调用者请求第三方帮助,也都可以扮演实现着去完成对应的请求。对于实现组件而已,不需要关注其调用者是谁,只需依照请求者发送的Intent对象去执行相关功能即可

【组件管理服务】在调用组件与实现组件的连接过程中,组件管理服务扮演了调度者的角色。从调用组件中接收到Intent对象,然后将该对象与应用管理服务收集到的组件Intent Filter对象进行比较,从中选择出符合调用组件需求的实现组件,最后构造并调用实现组件对象,组件管理服务是一个系统服务,运行在系统核心进程的独立线程中,通过进程间通信机制,与各组件进行交互

Intent对象的作用

Intent对象是组件间通信信息的载体。它封装了调用组件提供的指令和数据,通过组件管理服务序列化传递给实现组件,实现组件可以利用这些信息完成所需功能。 Intent对象定义了组件间连接协议。每个Intent对象都包含若干个数据项,每个数据项都有其内涵,调用者组件根据这些规范构造Intent对象描述其需求;实现组件根据这些规范解析Intent对象执行所需功能;而组件管理服务依照这些规范寻找与需求匹配的组件,构造连接

Intent对象的构成

Intent类的实现非常简单,只是包含了若干个数据项

  • Action项 Action就是用来表达动作的。Action就是一个字符串,可以用setAction函数为intent对象指定一个动作,也可以用getAction读取Intent对象中的动作信息。
  • Data项 意愿的表达,比如我吃宫保鸡丁,主语“我”,在意图机制下对应着调用组件,谓语“吃”,用Intent的Action对象来表达,宾语"宫保鸡丁"则对应着Data,setData,setDataAndType来进行设置,通过getData函数来读取。Data数据也是用字符串进行存储的,它的个数符合URI标准,URI具有丰富的表达能力,能够表达存储在任何地方的数据
  • Type项 如果Data用于特指,那么Type用于泛指,setType,setDataAndType,getType,Type是MIME格式的字符串数据,用于描述组件能够处理的请求类型,或者补充说明Data数据的类型。可以通过通配符*来表示整个类别的信息 在Intent对象中,Data项和Type项很多时候是互斥使用的。一个Intent中,需要Data表示数据还是用Type表示数据类型通常是和Action密切相关的。
  • Category项 category表示约束,每个Intent对象可包含多个Categories。addCategory添加Category项,getCategories获取该Intent对象Category项的集合。同一个Intent中的多个Category项彼此间是"与"关系。也就是说一个组件需要支持全部的Category项才能处理该请求。
  • Component项 Component指的是目标组件的类型信息,通过setComponent方法利用类名进行设定,也可以通过setClass方法利用类型对象信息进行设置。当调用组件明确了Component信息,组件管理服务就不再需要根据Action、Data等信息去寻找满足其需求的实现组件了。只需按照Component信息实例化对于的组件作为功能实现者即可。
  • Extras项 Extras是Intent中数据传输的载体,负责将数据从调用组件传递到实现组件。Extras是一个Bundle对象,该对象按照键值对的方式存储数据,它实现了Parcelable接口,可以进行数据的序列化和反序列化,从而在进程中传递。
  • Flags项 一个整形数,由一系列的标志位汇集而成。它对于实现组件而言完全透明,是调用组件指定组件管理服务构造实现组件的方式,常用于改变实现组件的任务模型和进程模型等。被设定的Flags标志位将会叠加生效。但需要注意的是,很多标志位之间是相关联逻辑关系的,有的标志位需要同时设定,而有的标志位直接则具有一定的互斥性。

Intent对象解析

组件管理服务负责接收和分析Intent对象。Intent对象可以分成两类:精确描述的Intent(Explicit Intent)和模糊描述的Intent(Implicit Intent) 精确描述的Intent,指的是所有带有Component信息的Intent对象。在精确描述的前提下,Intent对象只是作为消息的载体存在 模糊描述的Intent,对基于模糊描述的Intent调用组件而言,它们不在乎实现组件是谁,只要求该组件能够依照Intent对象中描述的意图和需求完成对应的任务。 精确描述的Intent通常用于应用内部的通信,因为调用组件和实现组件彼此了解,不需要动态机制,只需要最快地将消息传递过去就好了。 而模糊描述的Intent,则用于不同应用组件间的互联互通,它的存在将请求者和实现者完全解耦,极大地提升了系统的灵活性。

Intent Filter对象

与Intent相似,IntentFilter对象也包含Action、Type、Data、Category等数据项,每个数据项的结构和含义,与Intent中的数据项也一一对应。当组件管理服务接收到调用组件发送来的基于模糊描述的Intent对象时,会与所有组件的IntentFilter信息进行匹配技术,寻找符合需求的实现组件。 每个组件都可以有任意数量的IntentFilter,组件包含的Intent Filter对象越多,说明它能接受Intent请求的范围越广。而不添加任何Intent Filter对象的组件,仅能通过Intent对象精确地进行调用 组件对于的IntentFilter信息,一般通过配置文件的项进行添加,放在界面组件、服务组件或触发器组件的配置项中。

意图匹配的算法流程

Intent对象和Intent Filter对象的匹配过程,就称为意图匹配算法。 

算法输入的是进行比较的Intent对象和Intent Filter对象,输出的是一个32位的整数值,用于表征两者的匹配程度。 整个匹配算法的流程可分为3个步骤 1. Action的比较:每个IntentFilter对象都必须包含Action信息,如果没有,则对任何一个Intent对象都会匹配失败 2. Data和Type的比较:Data和Type信息是Intent Filter中最复杂的数据项,其比较算法是决定Intent与Intent Filter对象匹配程度的关键 3. Category的比较

匹配组件的选择

如果有多个Intent Filter对象与调用组件发出的Intent对象都相匹配,就需要在所有符合条件的Intent Filter对象中进行筛选,选出最符合调用组件和用户需求的实现组件,这个流程就称为匹配组件的选择。 在组件选择上,最核心的机制就是基于优先级的排序。每一个Intent Filter对象都有一个优先级,从-1000到1000,值越大,优先级越高 实例例子,如拦截短信,可以采取提升Intent Filter优先级的策略来实现:

    <receiver android:name="third_parth.SmsReceiver">
<intent-filter>
<action android:priority="1000"
android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>

在third_party.SmsReceiver这个触发组件中,系统可以定制策略拦截特定的短信,通过调用abortBroadcast()函数终止广播,使其他短信应用的Intent Filter无法匹配短信通知

public void onReceive(Context context,Intent intent)
{
if(IsBlockSms(intent))
abortBroadcast();
}

意图匹配的优化

意图机制中,引入第三方组件管理服务,降低了调用组件和实现组件之间的耦合,提高了系统的灵活性及组件的复用性,但同时,由于第三方服务地介入增加了组件间连接的成本,可能会使组件间的调用不够流畅。因此,系统对组件的匹配和选择过程进行了大量的优化,以提升意图匹配和组件调用的效率。

  • 索引:此流程涉及大量的字符串比较,比较耗时。组件管理服务会通过哈希表,为所有Intent Filter对象的Action、Type等数据项建立索引。每个索引对应着一组Action相同,Type相同,或者其他数据项相同的Intent Filter对象。Intent对象会先将其中的数据项与索引项进行比较,快速地选择出可能与Intent相匹配的Intent Filter对象。
  • 缓存:将Intent和Intent Filter的匹配结果记录下来,当再碰到相同的Intent的调用时,可直接返回上次记录的结果,从而跳过意图匹配的过程,加速组件的调用。服务组件,组件管理服务会在内存中通过哈希表的形式保留各个Intent对应的服务组件。

意图机制的应用

意图机制在界面组件中的应用

调用组件可以通过调用startActivity和startActivityForResult等函数发起对目标界面组件的调用,选择并构造出一个符合其需求的界面组件实例,切换至前台与用户进行交互。调用组件可以在构造的Intent对象中添加一些Flags标志位信息,用于告知组件管理服务如何去构造实现组件。当多个界面组件都能满足调用组件的需求,就需要从中选择一个最适合的组件作为最终的实现组件。对于界面组件的选择,需要兼顾效率和公平性。

  • 效率:选择过程中尽可能流畅
  • 公平性:每个符合调用者需求的组件,都应当具有同等的权利来响应调用组件的请求。 首先,通过算法对已排序的Intent Filter进行筛选,组件管理服务会将排序后队列中的第一个Intent Filter对象(记为A)与第二个Intent Filter对象(记作B)进行比较,如果满足一下条件中的一个,组件管理服务就会直接选择A对象对应的组件作为实现组件
  • A的优先级高于B
  • A包含intent.CATEGORY_DEFAULT,而B没有 同时,Android会将所有符合需求的组件列举起来,让用户决定选择哪个组件来执行该操作。用户可以选择该组件作为执行类似Intent调用的默认组件 如果调用组件期望绕过默认值的约束,让用户根据当前场景再次做出选择,可以通过Intent.createChooser方法自定义组件选择列表 activity.startActivity(Intent.createChooser(intent,R.strng.invite_friend));

意图机制在服务组件中的应用

调用组件可以调用Context.startService函数启动符合需求的服务组件,也可以通过Context.bindService函数绑定对应的服务组件。由于服务组件是在后台提供服务的,当出出现多个匹配项时,无法像界面组件一样构造交互界面让用户来抉择。因此,Android会默认选择优先级最高的组件作为实现组件。 这种情况下,只要备选组件没有变化,对于同一个Intent对象而言,其实现组件是固定的,因此,组件管理服务会记录Intent对象与其实现组件的对照关系,当再次通过相同的Intent对象请求服务时,就可以跳过组件匹配计算,直接返回实现组件。

意图机制在触发器组件中的应用

触发器组件的功能就是监听广播事件的Intent对象,并对其进行简单的解析和处理。调用组件调用sendBroadcast或sendOrderedBroadcast函数进行事件的广播。这些事件消息的载体就是Intent对象 用于广播事件中的Intent对象的Action项,与用于界面组件调用中Intent对象的Action项是完全分离的。 在触发器组件的构造中,不存在匹配组件选择的问题。

小结

Android的意图机制是Android应用模型的核心,解决了组件间的连接问题。通过组件管理服务提供的Intent对象与Intent Filter对象的匹配策略,降低了组件间的耦合度,提供了平台的灵活性,增强了组件的复用性,从而从根本上减轻了应用开发的负担。

【Android开发精要笔记】Android的Intent机制的更多相关文章

  1. 【Android开发精要笔记】Android组件模型解析

    Android组件模型解析 Android中的Mashup 将应用切分成不同类别的组件,通过统一的定位模型和接口标准将他们整合在一起,来共同完成某项任务.在Android的Mashup模式下,每个组件 ...

  2. Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式

    Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...

  3. 「Android 开发」入门笔记

    「Android 开发」入门笔记(界面编程篇) ------每日摘要------ DAY-1: 学习笔记: Android应用结构分析 界面编程与视图(View)组件 布局管理器 问题整理: Andr ...

  4. Android开发艺术探索笔记——View(二)

    Android开发艺术探索笔记--View(二) View的事件分发机制 学习资料: 1.Understanding Android Input Touch Events System Framewo ...

  5. Android开发艺术探索笔记—— View(一)

    Android开发艺术探索笔记 --View(一) View的基础知识 什么是View View是Android中所有控件的基类.是一种界面层控件的抽象. View的位置参数 参数名 获取方式 含义 ...

  6. Ubuntu虚拟机+ROS+Android开发环境配置笔记

    Ubuntu虚拟机+ROS+Android开发环境配置笔记 虚拟机设置: 1.本地环境:Windows 7:VMWare:联网 2.虚拟环境 :Ubuntu 14.04. 比較稳定,且支持非常多ROS ...

  7. 阿里内部资料:Android开发核心知识笔记共2100页,58万字,完整版开放下载

    作为一个3-5年的Android工程师,我们经常会遇到这些瓶颈: 1.技术视野窄长期在小型软件公司,外包公司工作,技术视野被限制的太厉害 2.薪资提升难初中级Android岗位薪资上升空间有限,基本上 ...

  8. Android开发艺术探索——第二章:IPC机制(中)

    Android开发艺术探索--第二章:IPC机制(中) 好的,我们继续来了解IPC机制,在上篇我们可能就是把理论的知识写完了,然后现在基本上是可以实战了. 一.Android中的IPC方式 本节我们开 ...

  9. Android开发艺术探索——第二章:IPC机制(上)

    Android开发艺术探索--第二章:IPC机制(上) 本章主要讲解Android的IPC机制,首先介绍Android中的多进程概念以及多进程开发模式中常见的注意事项,接着介绍Android中的序列化 ...

随机推荐

  1. Python代码审计中一些需要重点关注的项

    SQL注入: 如果是常规没有进行预编译,或者直接使用原生的进行拼凑,那么在view的时候就需要多去观察了 [PythonSQL预编译]https://www.cnblogs.com/sevck/p/6 ...

  2. 初识python(python的安装与运行)

    python--“优雅”.“明确”.“简单”的哲学定位 一.python的安装(Windows环境下) 1.在python官网下载安装文件 python的官方网址:https://www.python ...

  3. RSA_JS_PHP加密解密

    root@DESKTOP-I4OIMJC /cygdrive/e/html/RSA_JS_PHP/openssl/bin # ./openssl.exe OpenSSL> genrsa -out ...

  4. 13_java之final|static|包|匿名对象|代码块|内部类

    01final关键字概念 * A: 概述 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承, 或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承 ...

  5. Unexpected API Error. Please report this at http://bugs.launchpad.net/nova/ and attach the Nova API log if possible. <class 'sqlalchemy.exc.OperationalError'> (HTTP 500) (Request-ID: req-6ac88345-ce5a

    Unexpected API Error. Please report this at http://bugs.launchpad.net/nova/ and attach the Nova API ...

  6. Zedgraph悬停时显示内容闪烁的解决

    中修改 HandleCursorValues 如下形式即可. // weng modified on 20170531 1016 private Point lastMovedPoint; priva ...

  7. 使用EXCEL绘制三维地图(超简单的五分钟绘制地图方法,妈妈再也不用担心我不会画地图啦~)

    博主为从区域规划转行地图学的小学渣一枚,最近处理数据希望对结果进行三维可视化,意外发现从小用到大的EXCEL可以绘制地图且功能非常强大,在这里做一下简单介绍,希望可以给看官提供些许帮助.那下面就开始吧 ...

  8. python web框架简介Bottle Flask Tornado

    Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. ? 1 2 3 4 pip inst ...

  9. spring源码解析之AOP原理

    一.准备工作 在这里我先简单记录下如何实现一个aop: AOP:[动态代理] 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式: 1.导入aop模块:Spring AOP:(s ...

  10. 使用Eclipse搭建JavaWeb开发环境的几个基本问题

    Eclipse搭建JavaWeb开发环境 eclipse是一个用于java程序开发的ide软件,tomcat是一个运行javaweb应用的服务器软件,使用eclipse开发javaweb应用的时,首要 ...