Intent和IntentFilter的区别

Intent 用于启动 Activity,Service,  以及 BroadcastReceiver 三种组件 同时还是组件之间通信的重要媒介。

使用 Intent 启动组件的优势
1, Intent 为组件的启动提供了一致的编程模型。 无论想要启动的组件是 Activity,Service,  还是 BroadcastReceiver, 都可以使用 Intent 封装启动的意图。
2,  在某些时候 应用程序只是想启动具有某种特征的组件 并不想和某个特定的组件耦合。 使用 Intent 可以方便的达到这种高层次解耦的目的。

Intent Component 属性
Intent 对象的 setComponent(ComponentNamecomp) 方法用于设置 Intent Component 属性。 ComponentName 包含如下几个构造器 :
ComponentName(Stringpkg, String cls)
ComponentName(Contextpkg, String cls)
ComponentName(Contextpkg, Class<?> cls)
由以上的构造器可知 创建一个 ComponentName 对象需要指定包名和类名 -- 这就可以唯一确定一个组件类 这样应用程序即可根据给定的组件类去启动特定的组件。 例如 :
ComponentName comp =new ComponentName(FirstActivity this,SecondActivity class);
Intent intent = newIntent();
intent setComponent(comp);
以上三句代码创建了一个 intent 对象 并为其指定了 Component 属性 完全等价于下面的代码 :
Intent intent = newIntent(FirstActivity this,SecondActivity class);
除了使用 setComponent() 之外 还可以使用 setClass(),setClassName() 来显式指定目标组件 还可以调用 getComponent() 方法获得 Intent 中封装的 ComponentName 对象。
当程序采用这种形式启动组件时 Intent 中明确的指定了待启动的组件类 此时的 Intent 属于显式 intent,  显式 Intent 应用场合比较狭窄 多用于启动本应用中的 component, 因为这种方式需要提前获知目标组件类的全限定名。 而隐式 Intent 则通过 Intent 中的 action,category, data 属性指定目标组件需要满足的若干条件 系统筛选出满足所有条件的 component, 从中选择最合适的 component 或者由用户选择一个 component 作为目标组件启动。
如果 Intent 中指定了 ComponentName 属性 Intent 的其他属性将被忽略。

Intent Action 属性
action 属性是一个字符串 代表某一种特定的动作。  Intent 类预定义了一些 action 常量 开发者也可以自定义 action 一般来说 自定义的 action 应该以 application 的包名作为前缀 然后附加特定的大写字符串 例如 "cn xing upload action UPLOAD_COMPLETE" 就是一个命名良好的 action
Intent 类的 setAction() 方法用于设定 action,getAction() 方法可以获取 Intent 中封装的 action
以下是 Intent 类中预定义的部分 action:
ACTION_CALL-- 目标组件为 activity, 代表拨号动作 ;
ACTION_EDIT-- 目标组件为 activity, 代表向用户显示数据以供其编辑的动作 ;
ACTION_MAIN-- 目标组件为 activity, 表示作为 task 中的初始 activity 启动 ;
ACTION_BATTERY_LOW-- 目标组件为 broadcastReceiver, 提醒手机电量过低 ;
ACTION_SCREEN_ON-- 目标组件为 broadcast, 表示开启屏幕。

Intent Category 属性
category 属性也是一个字符串 用于指定一些目标组件需要满足的额外条件。  Intent 对象中可以包含任意多个 category 属性。  Intent 类也预定义了一些 category 常量 开发者也可以自定义 category 属性。
Intent 类的 addCategory() 方法为 Intent 添加 Category 属性 ,getCategories() 方法用于获取 Intent 中封装的所有 category
以下是 Intent 类中预定义的部分 category:
CATEGORY_HOME-- 表示目标 activity 必须是一个显示 homescreen activity;
CATEGORY_LAUNCHER-- 表示目标 activity 可以作为 task 栈中的初始 activity, 常与 ACTION_MAIN 配合使用 ;
CATEGORY_GADGET-- 表示目标 activity 可以被作为另一个 activity 的一部分嵌入。

Intent Data 属性
data 属性指定所操作数据的 URI  data 经常与 action 配合使用 如果 action ACTION_EDIT,data 的值应该指明被编辑文档的 URI;  如果
action ACTION_CALL,data 的值应该是一个以 "tel:" 开头并在其后附加号码的 URI;  如果 action ACTION_VIEW,data 的值应该是一个以 "http:" 开头并在其后附加网址的 URI 。。。
Intent 类的 setData() 方法用于设置 data 属性 ,setType() 方法用于设置 data MIME 类型 ,setDataAndType() 方法可以同时设定两者。 可以通过 getData() 方法获取 data 属性的值 通过 getType() 方法获取 data MIME 类型。

Intent Extra 属性
通过 Intent 启动一个 component 经常需要携带一些额外的数据过去。 携带数据需要调用 Intent putExtra() 方法 该方法存在多个重载方法 可用于携带基本数据类型及其数组 , String 类型及其数组 ,  Serializable 类型及其数组 ,Parcelable 类型及其数组 , Bundle 类型等。 Serializable Parcelable 类型代表一个可序列化的对象 , Bundle Map 类似 , 可用于存储键值对。

Intent Flag 属性
flag 属性是一个 int 用于通知 android 系统如何启动目标 activity, 或者启动目标 activity 之后应该采取怎样的后续操作。 所有的 flag 都在 Intent 类中定义 部分常用 flag 如下 :
FLAG_ACTIVITY_NEW_TASK-- 通知系统将目标 activity 作为一个新 task 的初始 activity;
FLAG_ACTIVITY_NO_HISTORY-- 通知系统不要将目标 activity 放入历史栈中 ;
FLAG_FROM_BACKGROUND-- 通知系统这个 Intent 来源于后台操作 而非用户的直接选择。。。

IntentFilter
IntentFilter 类表示 Intent 过滤器 大部分情况下 每一个 component 都会定义一个或多个 IntentFilter, 用于表明其可处理的 Intent  
一般来说 ,component IntentFilter 应该在 AndroidManifest xml 文件中定义。  
定义的方法 <activity>,<receiver>, <service> 元素中增加一个或多个 <intent-filter> 子元素。 :
<!--  声明作为程序入口的 Activity-->
<activityandroid:name=" FirstActivity">
       <intent-filter>
               <action android:name="android intent action MAIN"/>
               <category android:name="android intent category LAUNCHER"/>
       </intent-filter>
</activity>

IntentFilter 与隐式 Intent
android 系统处理隐式 Intent 会比较 Intent IntentFilter action,data, category 属性 如果以上 3 个属性全都相符的话 IntentFilter 所属的 component 就可以作为目标组件的候选 ( 存在多个符合条件的 component )  
1 测试 action 属性。  intent 最多只能定义 1 action,  filter 可以定义 1 个或多个 action  
通过 action 测试的条件为 : filter 定义了 intent action 例如 intent action "android intent action MAIN", 则定义了 "android intent action MAIN" 这个 action filter 都能通过 action 测试 ( 当然 , filter 还可以包含更多额外的 action)
如果 filter 没有定义 action,  则这个 filter 将阻塞所有 intent 如果 intent 没有定义 action,  那么只要 filter 定义了 action 就可以通过 action 测试。  
2 测试 category 属性。  intent 可以任意多个 category,filter 也可以任意个 category 通过 category 测试的条件为 : filter 定义了 intent 的所有 category 例如 intent 定义了 "android intent category DEFAULT" "cn xing intent category UPLOAD" 2 category, 则定义了以上 2 category 属性的 filter 才能通过测试 ( 当然 , filter 还可以包含更多额外的 category)
根据上面的规则 如果一个 intent 没有定义 category, 则所有 filter 都可以通过 category 测试。 但是有一种例外 startActivity(intent) 方式启动一个 activity 系统为会 intent 增加一个值为 "android intent category DEFAULT" category, 这就意味着每一个期望通过 category 测试的 activity, 都要在其 filter 中定义 "android intent category DEFAULT"( 除了作为程序入口的 activity)
3 测试 data 属性。  intent 最多只能定义 1 data,filter 则可以定义多个 data
通过 data 测试的条件为 :
a 如果 intent 没有指定 data data type, 则只有没有定义 data datetype filter 才能通过测试 ;
b 如果 intent 定义了 data 没有定义 datatype,  则只有定义了相同 data 且没有定义 datetype filter 才能通过测试 ;
c 如果 intent 没有定义 data 却定义了 datatype,  则只有未定义 data 且定义了相同的 datatype filter 才能通过测试 ;
d 如果 intent 既定义了 data 也定义了 datatype,  则只有定义了相同的 data datatype filter 才能通过测试。
data 属性是一个 URI, URI 中包含 scheme,host, post path,  典型的 URI :
scheme://host:port/path
scheme, host, post path 都是可选的。 比较 2 data 只比较 filter 中包含的部分。 比如 filter 的一个 data 只是指定了 scheme 部分 则测试时只是比较 data scheme 部分 只要两者的 scheme 部分相同 就视为 " 相同的 data"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值