安卓的基本设计思想是鼓励减少组件之间的耦合,所以安卓提供了Intent,它提供了一个通用的消息系统,允许在你的应用程序和其他应用程序之间传输Intent来执行动作和生成事件。使用意图激活安卓应用的三种核心组件:活动、服务和广播接收器。
意图可分为显性意图和隐性意图:
显式意图:调用意图。setcomponent() Entity . setclassname()或Intent。setclass()方法明确指定组件名称的意图是显式意图,显式意图明确指定要激活哪个组件。
隐含意图:没有明确指定组件名称的意图是隐含意图。安卓会根据隐含意图中设置的动作、类别和数据(URI和数据类型),找到最适合处理隐含意图的组件。对于隐含意图,Android如何找到最合适的组件?当我们定义活动时,我们指定一个意图过滤器,它实际上用于匹配隐含的意图。当意图过滤器测试意图对象时,将只引用三个方面:动作、数据(URI和数据类型)和类别。
动作测试
意图对象只能指定一个操作名,而过滤器可以枚举多个操作名。如果意图对象或过滤器未指定任何操作,结果如下:
如果过滤器没有指定任何操作,所有意图都将被阻止,因此所有意图都将无法通过测试。没有意图可以通过这个过滤器。
另一方面,只要过滤器包含至少一个动作,没有指定动作的预期对象将自动通过该测试。
类别测试
对于能够通过类别匹配测试的意图,意图对象中的类别必须与过滤器中的类别匹配。该过滤器可以列举其他类别,但不能在此意图中省略任何类别。
原则上,没有类别的有意对象应该总是通过匹配测试,而不管过滤器中有什么。很多时候,这是对的。然而,有一个例外。Android将传递给startActivity()的所有隐式意图视为至少包含一个类别:“Android . intent . category . default”(类别_ default常量)。因此,想要接收隐式意图的活动必须在其意图过滤器中包含“Android . intent . category . default”。(带有“android.intent.action.MAIN”和“Android . intent . category . launcher”设置的过滤器是个例外)
数据测试
当意图对象中的URI与过滤器中的URI相比较时,URI的分量被比较。例如,如果过滤器仅指定一个方案,则该方案的所有URIs都可以匹配该过滤器;如果筛选器指定了方案、主机名但没有路由部分,则所有具有相同方案和主机名的URIs都可以匹配此筛选器,而不管它们的路由如何;如果筛选器指定了方案、主机名和路径,则只有具有相同方案、主机名和路径的URIs才能匹配此筛选器。当然,过滤器中的路径规范可以包含通配符,因此只需要部分匹配。
数据测试比较意向对象和过滤器中指定的URI和数据类型。规则如下:
A.既不包含URI也不包含数据类型的意向对象只有在筛选器也未指定任何URIs和数据类型的情况下才能通过测试。
B.具有URI但没有数据类型的意图对象只有在它的URI与没有指定数据类型的过滤器中的URI匹配时才能通过测试。这种情况通常发生在URIs,如mailto:和tel:他们没有参考实际数据。
C.仅当筛选器列出了相同的数据类型并且未指定URI时,包含数据类型但不包含URIs的意图对象才能通过测试。
D.如果包含URI和数据类型(或者可以从URI推断出数据类型)的意图对象的类型与过滤器中列出的类型匹配,则该对象可以通过测试。如果它的URI匹配此过滤器中的URI,或者它具有内容:或文件: URI,并且此过滤器未指定URI,则它可以通过测试。换句话说,如果一个组件的筛选器只列出一种数据类型,则认为该组件支持content:和file:数据。