【Android开发精要笔记】Android的Intent机制

Android的Intent机制

Intent对象的做用和构成

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

  • 经过组件的配置信息了解系统中每一个组件的类别和功能
  • 帮助调用组件寻找符合其需求的实现组件,将调用者与实如今完全解耦

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

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

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

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

Intent对象的做用

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

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对象的匹配策略,下降了组件间的耦合度,提供了平台的灵活性,加强了组件的复用性,从而从根本上减轻了应用开发的负担。

 

相关文章
相关标签/搜索