首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

Android中的Intent Filter与保险

2012-09-11 
Android中的Intent Filter与安全更多原文请见:http://mobile.51cto.com/abased-349323.htmIntent是Android

Android中的Intent Filter与安全
更多原文请见:http://mobile.51cto.com/abased-349323.htm  Intent是Android应用程序核心组件之间通信和传递信息的核心机制。与之相关的IntentFilter也具有相关的安全机制(测试)来进行约束。本文将对其进行详细介绍。 一、Intent和IntentFilter简介一个应用程序的三个核心组件(活动,服务和广播接收器)都是通过消息即意图(Intents)来激活的。Intent消息传送是相同或不同应用中组件运行时晚绑定的一种机制。意图本身(一个意图对象)是一个包含被执行操作抽象描述的被动的数据结构。或,对于广播而言,是某件已经发生并被声明的事情的描述。存在如下几种不同的机制来传送意图到每种组件中:一个意图对象是传递给Context.startActivity()或者Activity.startActivityForResult()来启动一个活动或者让一个存在的活动去做某些新的事情。一个意图对象是传递给Context.startService()来发起一个服务或者递交新的指令给运行中的服务。类似的,一个意图能被传递给Context.bindService() 来在调用组件和一个目标服务之间建立连接。作为一个可选项,它可以发起这个服务如果还没运行的话。 传递给任意广播方法(例如Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast())的意图对象被传递给所有感兴趣的广播接收者。许多种广播产生于系统代码。在每个例子里,Android系统找到合适的活动、服务或者一组广播接收者来回应这个意图,必要时实例化它们。这些消息传送系统没有重叠:广播意图仅被传递给广播接收者,永远不会给活动或者服务。一个传送给startActivity()的意图是只会被传递给一个活动,永远不会给一个服务或广播接收者,如此类推。为了通知系统它们可以处理哪些意图,活动、服务和广播接收器可以有一个或多个意图过滤器。每个过滤器描述组件的一个能力,一系列组件想要接收的意图。它实际上按照一个期望的类型来进行意图滤入,同时滤出不想要的意图-但是只有不想要的隐式意图会被滤出(那些没有命名目标的对象类)。一个显式意图总能够被递交给它的目标,而无论它包含什么。这种情况下过滤器不起作用。但是一个显式意图仅当它能通过组件的一个过滤器时才可以被递交到这个组件。组件为它能做的每项工作,每个呈现给用户的不同方面分有不同的过滤器。比如,范例记事本应用程序中的主要活动有三个过滤器:一个是空白板,另一个是用户可以查看、编辑、或选择的一个指定的记事目录,第三是在没有初始目录说明的情况下查找一个特定的记录。一个意图过滤器是IntentFilter类的一个实例。但是,由于Android系统在启动一个组件前必须知道这个组件的能力,意图过滤器通常不会用Java代码来设置,而是在应用程序清单文件(AndroidManifest.xml)中设置<intent-filter>元素。(有一个例外,通过调用Context.registerReceiver()来注册的广播接收器的过滤器;它们是作为意图过滤器对象而被直接创建的。  二 、过滤器与安全Filters and security我们不能信赖一个意图过滤器的安全性。当它打开一个组件来接收某些特定类型的隐式意图,它并不能阻止以这个组件为目标的显式意图。即使过滤器对组件要处理的意图限制某些动作和数据源,总有人能把一个显式意图和一个不同的动作及数据源组合在一起,然后命名该组件为目标。一个过滤器和意图对象有同样的动作、数据以及类别字段。一个隐式意图在过滤器的所有三个方面都被测试。为了递交到拥有这个过滤器的组件,它必须通过所有这三项测试。即便只有一个不通过,Android系统都不会把它递交给这个组件。不过,由于一个组件可以包含多个意图过滤器,一个不能通过其中一个组件过滤器的意图可能在另外的过滤器上获得通过。与之相关的三个测试详细描述如下:测试一:动作测试(Actiontest)清单文件中的意图过滤器元素里列举了动作元素,比如:

    scheme://host:port/path比如,在下面的URI里面,content://com.example.project:200/folder/subfolder/etc模式是"内容",主机是"com.example.project",端口是"200",路经是"folder/subfolder/etc"。主机和端口一起组成URI鉴权(authority);如果未指定主机,端口会被忽略。这些属性都是可选的,但彼此有依赖关系:一个授权要有意义,必须指定一个模式。一个路经要有意义,必须同时指定模式和鉴权。当一个意图对象中的URI被用来和一个过滤器中的URI规格比较时,它实际上比较的是上面提到的URI的各个部分。比如,如果过滤器仅指定了一个模式,所有那个模式的URIs和这个过滤器相匹配;如果过滤器指定了一个模式、鉴权但没有路经,所有相同模式和鉴权的URIs可以匹配上,而不管它们的路经;如果过滤器指定了一个模式、鉴权和路经,只有相同模式、鉴权和路经的URIs可以匹配上。当然,一个过滤器中的路径规格可以包含通配符,这样只需要部分匹配即可。数据<data>元素的类型属性指定了数据的MIME类型。这在过滤器里比在URI里更为常见。意图对象和过滤器都可以使用一个"*"通配符指定子类型字段-比如,"text/*"或者"audio/*"-指示任何匹配的子类型。数据测试同时比较意图对象和过滤器中指定的URI和数据类型。规则如下:1) 一个既不包含URI也不包含数据类型的意图对象仅在过滤器也同样没有指定任何URIs和数据类型的情况下才能通过测试。2) 一个包含URI但没有数据类型的意图对象仅在它的URI和一个同样没有指定数据类型的过滤器里的URI匹配时才能通过测试。这通常发生在类似于mailto:和tel:这样的URIs上:它们并不引用实际数据。3) 一个包含数据类型但不包含URI的意图对象仅在这个过滤器列举了同样的数据类型而且也没有指定一个URI的情况下才能通过测试。4) 一个同时包含URI和数据类型(或者可从URI推断出数据类型)的意图对象可以通过测试,如果它的类型和过滤器中列举的类型相匹配的话。如果它的URI和这个过滤器中的一个URI相匹配或者它有一个内容content:或者文件file: URI而且这个过滤器没有指定一个URI,那么它也能通过测试。换句话说,一个组件被假定为支持content:和file: 数据如果它的过滤器仅列举了一个数据类型。如果一个意图可以通过不止一个活动或服务的过滤器,用户可能会被询问要激活那个组件,并且,如果没有发现目标对象将会出现异常。

热点排行