`
zhubin215130
  • 浏览: 142359 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

[转]Intent 解析

阅读更多

基于组件的架构体系,除了有定义良好的组件,如何把这些组件组装在一起,也是一门艺术。在Android中,Intent (貌似通常译作:意图 ...),就是连接各组件的桥梁。
前段时间看同事们做Symbian平台的网易掌上邮 (真 的是做的用心,NB的一米,热情欢迎所有163邮箱的S60v3用户,猛点击之...),有个功能是为邮件添加附件,比如你想要通过邮件发送一副图片泡 mm,可能需要有个很直观的方式从本地选一副珍藏美图,抑或是拿相机来个完美自拍。在Symbian中,这样的功能,都需要你用底层的API,自己一点点 写。为了让选图片体验更好,可能需要做一个类似于图片浏览器之类的东西,为了把拍照做的更为顺畅,甚至需要实现从聚焦到调节亮度之类一整套的相机功能。
而其实呢,用户的手机中可能本身就装了其他的专 业图片浏览器、相机等应用,这些应用已经非常出色好用,而用户也已然能很纯属使用它们,如果能进行调用,对邮箱的开发者和用户而言,都会是个更好的选择。 但在Symbian这样残败的系统里,应用和应用之间的结合能力奇弱无比,想复用,基本比登天还难,作为开发者,只能忍住一次又一次的恶心,为了用户,做 这些重复造轮子吃力不讨好的附加工作。
还好还好,在Android中,一切变得美好多 了,它将开发者从接口和对象的细节中解救出来,让我们有更多精力投入到核心功能的开发中去。在Android中,如果你需要选个图拍个片,只需要构造一个 描述你此项意愿的Intent,发送出去,系统会帮你选择一个能够处理该项业务的组件来满足你的需求,而不再需要纠结在具体的接口和实现 上,Perfect World,便应如此。

Intent构成

Intent被译作意图,其实还是很能传神的,Intent期望做到的,就是把实现者和调用者完全解耦,调用者专心将以意图描述清晰,发送出去,就可以梦想成真,达到目的。
当然,这么说太虚了,庖丁解牛,什么东西切开来看看,也许就清晰了。Intent reference/android/content/Intent.html ),在Android中表现成一个类,发起一个意图,你需要构造这样一个对象,并为下列几项中的一些进行赋值:

  1. Action 。当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想 三个俯卧撑;我要 一部x片;我要 一部血泪史,之类云云。在Intent中,Action就是描述看、做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEWACTION_PICK ,之类的,基本涵盖了常用动作,整一个降龙十八掌全集。当然,你也可以与时俱进,创造新的动作,比如lou这样的。与系统预定义的相比,这些自定义动作的流通范围很是有限,除非做了非常NB的应用,大家都需要follow你,否则通常都是应用内部流通。
  2. Data 。当然,光有动作还是不够的,还需要有更确切的对象信息。比如,同样是 这个动作,但泡咖啡 ,和泡妞 ,就差之千里了。Data的描述,在Android中,表现成为一个URI 。用在内部通信中,可能描述是Content Provider用的形如content://xxxx 这样的东东,抑或是外部的一个形如tel://xxxx 这样的链接。总而言之,是能够清楚准确的描述一个数据地址的uri。
  3. Type 。说了 Data,就必须要提Type,很多时候,会有人误解,觉着Data和Type的差别,就犹如泡妞泡马子 之间的差别一样,微乎其微。但其实不然,Type信息,是用MIME 来表示的,比如text/plain , 这样的东西。说到这里,两者差别就很清晰了,Data就是门牌号,指明了具体的位置,具体问题具体分析,而type,则是强调物以类聚,解决一批量的问 题。实际的例子是这样的,比如,从某个应用拨打一个电话,会发起的是action为ACTION_DIAL且data为tel:xxx这样的 Intent,对应的人类语言就是拨打xxx的电话 ,很具象。而如果使用type,就宽泛了许多,比如浏览器收到一个未知的MIME类型的数据(比如一个视频...),就会放出这样的Intent,求系统的其他应用来帮助,表达成自然语言应该就是:查看 pdf类文档 ,这样的。
  4. Category 。通过Action,配合Data或Type,很多时候可以准确的表达出一个完整的意图了,但也会有些时候,还需要加一些约束在里面才能够更精准。比如,如果你虽然很喜欢做俯卧撑,但一次做三个还只是在特殊的时候才会发生,那么你可能表达说:每次吃撑了的时候 , 我都想做三个俯卧撑。吃撑了,这就对应着Intent的Category的范畴,它给所发生的意图附加一个约束。在Android中,一个实例是,所有应 用主Activity(就是单独启动时候,第一个运行的那个Activity...),都需要能够接受一个Category为 CATEGORY_LAUNCHER,Action为ACTION_Main的意图。
  5. Component 。在此之前,我们企图用Action,Data/Type,Category去描述一个意图,这是Android推荐,并期望大家在大多数时候使用的,这样模式在Android中称做Implicit Intents , 通过这种模式,提供一种灵活可扩展的模式,给用户和第三方应用一个选择权。比如,还是一个邮箱软件,他大部分功能都好,就是选择图片的功能做的很土,怎么 办?如果它采用的是Implicit Intents,那么它就是一个开放的体系了,手机中没有其他图片选择程序的话,可以继续使用邮箱默认的,如果有,你可以任意选择来替代原有模块完整这功 能,一切都自然而然。但这种模式,也不是没有成本,需要付出的是一些性能上的开销,因为毕竟有一个检索过程。于是,Android提供了另一种模式,叫做Explicit Intents ,就需要Component的帮助了。Component就是类名 ,完整的,形如com.xxxxx.xxxx ,一旦指明了,一切都清晰了,找的到这个类(当然会是一个特定的子类...),成功,反之,失败。这个好处,自然是速度,适合在你明确知道这就是一个内部模块的时候,使用它。
  6. Extras 。通过上面的这些项,识别问题,基本完美解决了,剩下一个重要的问题,就是传参。Extras是用来做这个事情的,它是一个Bundle 类的对象,有一组可序列化的key/value对 组成。每一个Action,都会有与之对应的key和value类型约定,发起Intent的时候,需要按照要求把Data不能表示的额外参数放入Extras中(当然,如果不需要额外附加参数,就算了...),否则执行者拿到的时候会抓狂的。
  7. Flags 。 能识别,有输入,整个Intent基本就完整了,但还有一些附件的指令,需要放在Flags中带过去。顾名思义,Flags是一个整形数,有一些列的标志 位构成,这些标志,是用来指明运行模式的。比如,你期望这个意图的执行者,和你运行在两个完全不同的任务中(或说进程也无妨吧...),就需要设置FLAG_ACTIVITY_NEW_TASK 的标志位。

有了上述这些,一个Intent的形象就跃然纸上了,如此丰富的内容,决定了它比传统的模式,都来得强大。

Intent匹配

上次在moto dev上,听人做Android的讲座,下面有很多听客都对Intent这个概念表示出了强烈的兴趣,拿出自己熟悉领域的各类概念进行类比,比如事件、消 息之类。当时我在想,Intent作为组件间的通信协定,与一般的简单的通信方式不同,首先,从前面部分可以看到,它的描述是针对需求而不是实现者来进行 的。其次,它的解析是依托第三方而不是两方直接进行。
这个概念和设计模式中的中介模式(Mediator Pattern )是一脉的,即所有的外围组件,都只和系统的核心模块发生联系,通过它进行中转,组件之间不直接勾搭。



如上图所示,要想跑通整个流程,另一个很重要的东西,就是Intent Filters , 它是用来描述一个Activity或 Serveice等组件,期望能够响应怎么样的Intent。如果一个组件,只希望别的组件通过Explicit Intents(就是指明Component...)的方式来找到它,那么就不需要添加Intent Filters,反之,一定需要一个或若干个Intent Filters。Intent Filter的各个项,犹如Intent照镜子过来的效果,包括Action,Catagory,Data,Type等。
Intent Filters可以写到配置文件中,和那些组件的配置一起(不记得什么是配置文件了,可以看这里 ...),若干的实例可以在Intent介绍页面上找到(reference/android/content/Intent.html )。同样,Intent Filters可以在代码中,动态插拔,这个是和动态插拔的Broadcast Receiver 是配套使用的。
系统核心的模块,会负责收集这些Intent Filters,和它们对应的组件信息。当请求者需要一个组件帮忙,并构造了描述它需求的Intent发送到系统核心,系统核心会将其与已知的各个 Intent Filters进行匹配,挑选一个符合需求的组件返回。如果有多个符合的,会尝试看看有没有默认执行的,如果没有默认的,就会构造UI,让用户帮助抉择, 如是,整个流程就跑通了。

Intent实现




上图,是请求一个Activity组件的简单实现流程图,算是用的最多的 Intent解析实例。流程从调用Context.startActivity(Intent) 开始,调用者传入构造好的Intent对象,然后流程会让实际的执行者,是Instrumentation 对象来完成。它是整个应用激活的 Activity管理者,集中负责该应用内所有Activity的起承转合生离死别。它有一个隐藏的方法execStartActivit y 方法,就是负责根据Intent启动Activity的。去掉一些细节,它做得最重要的事情,就是将此调用,通过RPC的方式,传递到ActivityManagerService
前面一直再说,系统核心层 ,其实这里所谓的系统核心层,就是负责Android一些关键事务的一组服务 。它们同样运行在虚拟机上,和普通的Service实现机理是一致的,只不过它们不抛头露脸只是默默的在下层服务,故谓之核心嘛。 AcitivityManagerService,是负责Activity调度的服务,也许日后提及调度细节的时候还会有涉及。
在这里,AcitivityManagerService 会分两个步骤完成相关操作,首先把Intent递交给另一个服务PackageManagerService , 此服务掌握整个软件包及其各组件的信息,它会将传递过来的Intent,与已知的所有Intent Filters进行匹配(如果带有Component信息,就不用比了...),找到了,就把相关Component的信息通知回 AcitivityManagerService,在这里,会完成启动Activity这个很多细节的事情。
由此可知,启动Activity,要经过多个服务的处理,并不是非常轻量的过程,在Android随机文档介绍性能 的一节中,对此有一个评估。但这样的操作不是会放在循环里反复折磨的那种,因此整体效果与其付出的性能代价相比,觉得是物超所值的。

分享到:
评论

相关推荐

    intent匹配规则大总结

    本文将围绕给定文件提供的信息,深入解析Intent匹配规则的关键点,并结合具体示例帮助理解。 #### 一、Intent与Activity的匹配基础 Intent与Activity之间的匹配基于`<intent-filter>`标签进行配置。`<intent-...

    Android的Intent实验

    8. **Intent解析** 当收到一个隐式Intent时,系统会检查所有已注册的组件,判断它们是否能够处理这个Intent。组件通过声明Intent过滤器(Intent Filter)来表明它们可以处理哪些Intent。过滤器包含动作、数据URI、...

    intent使用源码

    Component属性允许我们直接指定要启动的组件类名,这样就不需要依赖系统的Intent解析。 当我们调用Activity的`startActivity(Intent)`或Service的`startService(Intent)`方法时,系统会通过PackageManager服务解析...

    Android开发教程之Intent详细讲解--千锋培训

    二、Android如何解析Intent 当一个Intent被创建并传递时,Android系统会根据其描述进行解析,查找匹配的组件。解析过程主要考虑以下因素: 1. **动作匹配**:系统遍历Manifest文件中的所有声明,寻找具有与Intent...

    Intent系统调用示例

    本篇文章将详细解析“Intent系统调用示例”,并结合提供的IntentDemo项目进行深入探讨。 1. **Intent的基本概念** Intent是一个消息对象,它封装了应用程序想要执行的操作以及操作所需要的数据。在Android中,...

    Android应用源码之Intent_Intent.zip

    本资源包“Android应用源码之Intent_Intent.zip”应该包含了关于Intent使用的一些示例代码和解析,帮助开发者深入理解Intent的工作原理。 1. **Intent的类型** Intent主要有两种类型:显式Intent和隐式Intent。...

    Intent学习

    六、Intent的解析与选择 当发送一个隐式Intent时,系统会遍历所有注册的IntentFilter,找到最适合处理该Intent的组件。这个过程涉及到Intent Resolution和Component Selection算法,开发者应确保IntentFilter设置得...

    Android源码——Intent切换.zip

    3. **Intent解析与匹配**: - 系统通过`PackageManager`服务和`IntentFilter`来解析和匹配Intent。IntentFilter是组件(如Activity)声明它可以处理的Intent类型。 - 当发送隐式Intent时,系统会遍历所有注册的...

    android Intent的用法

    本篇文章将详细解析Intent的用法。 首先,Intent分为显式Intent和隐式Intent两种类型。显式Intent明确指定要启动的目标组件,通过组件的全限定类名(包名+类名)来指定。而隐式Intent则是不指定具体组件,而是通过...

    system-Intent

    同时,为了提供良好的用户体验,应该始终在调用`startActivity()`之前使用`resolveActivity()`检查Intent是否可以被解析。 在"androidtest"这个项目中,可能包含了用于演示这些功能的代码示例,你可以通过查看源...

    android intent 的生命周期讲解和历程

    本文将深入解析Intent的生命周期,并结合源码进行详细讲解。 首先,理解Intent的基本概念。Intent是一个消息对象,它封装了执行操作的信息,如启动一个Activity或者Service。Intent主要有两种类型:显式Intent和...

    Intent的启动

    本文将深入解析Intent的启动过程及其在Android应用开发中的关键作用。 一、Intent的基本概念与类型 Intent是Android系统中的一种消息对象,它封装了应用程序想要执行的操作和操作所需的数据。Intent主要有两种类型...

    android各种文件的intent

    根据提供的文件信息,我们可以深入探讨如何在Android应用中创建不同类型的文件Intent,以便与其他应用程序共享或打开特定格式的文件。 ### 一、Android中的Intent机制简介 在Android开发中,`Intent`是一种消息...

    intent属性

    Intent是Android系统中的一种核心机制,它用于在应用程序的不同组件之间传递消息,是实现组件间通信的主要...在实际开发中,应根据需求合理选择Intent类型,正确设置和解析Intent属性,以实现不同组件之间的无缝协作。

    android各组件详解- Intent.

    本文将从多个角度解析Intent的功能、应用场景及其内部结构,为开发者提供全面的理解。 ### Intent概述 Intent是Android平台上的核心概念之一,充当着应用程序内部以及不同应用程序之间通信的桥梁。它是一种用于...

    使用Intent打开网页

    这里用Uri.parse()方法解析URL,然后通过setData()方法设置到Intent中。 3. 启动Intent: ```java startActivity(intent); ``` 使用startActivity()方法启动Intent,系统会自动寻找能够处理此Intent的组件(在...

Global site tag (gtag.js) - Google Analytics