Android中Intent对象与Intent Filter过滤匹配过程详解

如果对Intent不是特别了解,可以参见博文《Android中Intent概述及使用》,该文对本文要使用的action、category以及data都进行了详细介绍。

本文内容有点长,希望大家可以耐心读完。

本文在描述组件在manifest中注册的Intent Filter过滤器时,统一用intent-filter表示。

概述

我们知道,Intent是分两种的:显式Intent和隐式Intent。如果一个Intent明确指定了要启动的组件的完整类名,那么这个Intent就是显式Intent,否则就是隐式Intent。当我们用一个显式Intent去启动组件时,Android会根据Intent对象所提供的component name直接找到要启动的组件,当我们用一个隐式的Intent去启动组件时,Android系统就无法直接知道要启动的组件名称了,本文就是讲解Android系统如何根据隐式Intent查找匹配到要启动的组件。

当Android系统接收到一个隐式Intent要启动一个Activity(或其他组件)时,Android会根据以下三个信息比较Intent的信息与注册的组件的intent-filter的信息,从而为该Intent选择出最匹配的Activity(或其他组件):

也就是隐式intent对象要满足要启动的目标组件中注册的intent-filter中的<action />、<category />、<data />三个标签中的信息,即要分别通过action测试、category测试以及data测试。intent-filter信息是在Android的manife文件中描述的,顾名思义,intent-filter是intent过滤器,就是用来过滤intent的。

如果隐式intent对象同时通过了某个组件的中intent-filter的action测试、category测试以及data测试,那么该组件就可以被intent对象所启动。如果隐式intent对象没有通过系统中任何组件的intent-filter测试,那么就没有Android系统无法找到该intent对象要启动的组件。下面我们依次看一下如何才能通过这三个测试。

Action测试

为了指定能够接收并处理的Intent的类型,组件可以在intent-filter中声明其支持0个或多个action,例如:

===”android.intent.category.DEFAULT” /></intent-filter>

intent对象可以通过setAction()方法设置唯一的一个action值。对于action测试,需要分两种情况:

intent对象设置了action 如果intent对象通过调用setAction()方法设置了action的值,那么只有当组件的intent-filter中包含了intent对象中的action值的时候,action测试才通过,否则无法通过。 举个例子,假设我们的Activity的intent-filter如下所示:

====>

下面的intent对象可以通过上面intent-filter里面的action测试:

Intent intent = new Intent();intent.setAction(“com.ispring.action.ACTION_TEST1”);Uri uri = Uri.parse(“ispring://blog.csdn.net/sunqunsunqun”);intent.setData(uri);

该intent之所以能通过action测试是因为intent-filter中包含该intent的action值com.ispring.action.ACTION_TEST1。

下面的intent对象无法通过上面intent-filter里面的action测试:

Intent intent = new Intent();intent.setAction(“com.ispring.action.ACTION_TEST3”);Uri uri = Uri.parse(“ispring://blog.csdn.net/sunqunsunqun”);intent.setData(uri);

该intent之所以无法通过action测试是因为intent-filter中不包含该intent的action值com.ispring.action.ACTION_TEST3。

intent对象没有设置action 如果intent对象没有调用setAction()方法设置action的值,那么如果intent-filter至少有一个任意的action的值,该intent对象就可以通过该intent-filter的action测试,反之,如果intent-filter中没有定义任何的action,那么该intent无法通过该intent-filter的action测试。 举个例子,假设我们的intent对象如下所示:

Intent intent = new Intent();//不设置action值//intent.setAction(“com.ispring.action.ACTION_TEST1”);Uri uri = Uri.parse(“ispring://blog.csdn.net/sunqunsunqun”);intent.setData(uri);

上面的intent对象可以通过如下的intent-filter:

===>

上面的intent对象无法通过如下的intent-filter:

==>

通过上面的几个示例,想必大家都已经理解了action测试的规则,,至于上面的category和data标签的使用,会在下面详细介绍。

总结起来有两点结论: 1. 要想让intent对象通过action测试,那么intent-filter中声明的action不能为空且要包含intent对象中的action值(如果intent的action值不为空的话)。 2. 如果intent-filter没有声明任何action,那么所有的intent的对象(即无论intent如何配置)都无法通过intent-filter的action测试。

Category测试

为了指定能够接收并处理的Intent的类型,组件可以在intent-filter中声明其支持0个或多个category,例如:

<intent-filter><category android:name=”android.intent.category.DEFAULT” /><category android:name=”android.intent.category.BROWSABLE” />…</intent-filter>

intent对象有addCategory()方法,也就是说一个intent对象也可以关联多个category。为了能让intent对象通过intent-filter的category测试,intent对象中的所有category都要在intent-filter中找到对应项。 具体来说,又分为如下两种情况:

intent对象至少有一个category 这种情况下,假设intent对象有N个category(N >=1),那么intent-filter中必须要包含这N个category,intent对象才能通过category测试,否则无法通过测试。如果用intent对象启动Activity,还有其他限制条件,会在后面详细说明。 举个例子,假设我们的intent-filter如下所示:

====”com.ispring.category.TEST2″ /></intent-filter>穷则思变,差则思勤!没有比人更高的山没有比脚更长的路。

Android中Intent对象与Intent Filter过滤匹配过程详解

相关文章:

你感兴趣的文章:

标签云: