`
coolxing
  • 浏览: 874172 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
9a45b66b-c585-3a35-8680-2e466b75e3f8
Java Concurre...
浏览量:97281
社区版块
存档分类
最新评论

android笔记--Intent和IntentFilter

阅读更多

[coolxing按: 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正.] 


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


使用Intent启动组件的优势

1, Intent为组件的启动提供了一致的编程模型. 无论想要启动的组件是Activity, Service, 还是BroadcastReceiver, 都可以使用Intent封装启动的意图.

2, 在某些时候, 应用程序只是想启动具有某种特征的组件, 并不想和某个特定的组件耦合. 使用Intent可以方便的达到这种高层次解耦的目的.


Intent的Component属性

Intent对象的setComponent(ComponentName comp)方法用于设置Intent的Component属性. ComponentName包含如下几个构造器:

ComponentName(String pkg, String cls)

ComponentName(Context pkg, String cls)

ComponentName(Context pkg, Class<?> cls)

由以上的构造器可知, 创建一个ComponentName对象需要指定包名和类名--这就可以唯一确定一个组件类, 这样应用程序即可根据给定的组件类去启动特定的组件. 例如:

ComponentName comp = new ComponentName(FirstActivity.this, SecondActivity.class);

Intent intent = new Intent();

intent.setComponent(comp);

以上三句代码创建了一个intent对象, 并为其指定了Component属性, 完全等价于下面的代码:

Intent intent = new Intent(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必须是一个显示home screen的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 -->

<activity android: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和date type的filter才能通过测试;

b. 如果intent定义了data没有定义data type, 则只有定义了相同data且没有定义date type的filter才能通过测试;

c. 如果intent没有定义data却定义了data type, 则只有未定义data且定义了相同的data type的filter才能通过测试;

d. 如果intent既定义了data也定义了data type, 则只有定义了相同的data和data type的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".

 

2
0
分享到:
评论

相关推荐

    Android笔记(3)---Activity和Intent

    Intent的解析和匹配则涉及到IntentFilter的比较算法,这是Android系统实现组件间通信的关键部分。 总结来说,Activity是Android应用程序的基本视图单元,Intent则是组件间通信的桥梁。掌握Activity的生命周期管理和...

    萌新Android笔记—-IntentFilter匹配篇

    Android的匹配机制也是给萌新当头一棒。但萌新突出一个莽字,不知道的东西就冲塔搞他。。首先我们萌新知道的启动activity分为两种,显式调用和隐式调用。原则上一个Intent不能即是显式调用又是隐式调用,两者真共存...

    android学习笔记2--BroadcastReceiver

    总之,BroadcastReceiver是Android系统中一种强大的通信工具,它可以监听并响应各种系统和应用事件,从而实现组件间的交互。正确理解和使用BroadcastReceiver能够提升应用的功能性和用户体验。在设计和编写...

    Android代码笔记齐全

    这份"Android代码笔记齐全 入门教程"显然是一个全面的学习资源,旨在帮助初学者逐步掌握Android应用开发的基础和进阶内容。下面,我们将深入探讨这些知识点,按照压缩包中文件名的顺序进行。 **day01**通常涵盖的是...

    Android学习笔记(三五):再谈Intent(下)-一些实践.doc

    另一种是模糊匹配,通过指定Action和Uri,如`Intent.ACTION_VIEW, uri`,这样可以启动符合该Action和数据类型的任何注册了相应IntentFilter的Activity。 启动Activity有以下两个关键步骤: 1. 创建Intent:Intent...

    二维码扫描笔记源代码--简单好用

    在IT行业中,尤其是在移动应用开发领域,二维码...总之,这个“二维码扫描笔记源代码”项目涵盖了Android应用开发中的多个核心知识点,从基本的用户界面设计到复杂的功能实现,为开发者提供了一个学习和参考的实例。

    疯狂Android讲义8-11.zip

    通过学习这一章,你可以理解如何创建和管理Activity,以及如何使用Intent传递数据和启动不同组件。 **第九章:IntentFilter与BroadcastReceiver** IntentFilter是Intent的接收者过滤器,用于定义一个组件(如...

    有用的android笔记

    Android四大组件包括活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)和内容提供者(ContentProvider)。这些组件共同构成了Android应用程序的基础。 - 活动(Activity)是用户与应用交互的界面,负责...

    Android开发教程&笔记

    这份“Android开发教程&笔记”旨在为初学者提供一个全面的学习路径,帮助他们从零基础开始掌握Android应用开发的核心概念和技术。 1. **Android基础知识** - Android系统架构:了解Android的分层结构,包括Linux...

    Android学习笔记(十八)——使用意图筛选器和实现浏览网页(附源码)

    总结,这篇学习笔记详细介绍了如何在Android应用中使用意图筛选器来处理隐式Intent,以及如何利用WebView组件来实现浏览网页的功能。通过源码,开发者可以更好地理解这两个概念,并在实际项目中进行实践。理解并掌握...

    Android学习笔记之NFC近距离无线通讯技术(Dean)(转载)

    **Android学习笔记之NFC近距离无线通讯技术** NFC(Near Field Communication)是一种短距离的高频无线通信技术,允许电子设备之间进行非接触式点对点数据交换。在Android系统中,NFC功能广泛应用于移动支付、数据...

    Android开发教程笔记完全版.zip

    这份"Android开发教程笔记完全版.zip"包含了一份详细的Android编程学习资源,可能是由一位经验丰富的开发者或教育者整理而成,旨在帮助初学者和有经验的开发者深入理解Android应用开发。 **Android系统架构** ...

    Android开发笔记

    ### Android开发笔记 #### Intent 广播机制 在Android应用开发过程中,经常需要实现不同组件间的通信,其中一种常见的通信方式就是使用`Intent`广播机制。`Intent`广播是一种允许发送一个`Intent`到所有已经注册...

    android学习笔记

    - **Intent和IntentFilter**:Intent用于在组件之间传递消息,IntentFilter则定义一个BroadcastReceiver可以响应的意图类型。 - **Service**:在后台执行长时间任务的服务。 - **ContentProvider**:用于在不同应用...

    Android培训机构教程大纲

    - **Android原生(C/C++)程序开发及Android NDK介绍**:介绍如何使用C/C++语言进行Android原生应用开发,以及Android Native Development Kit(NDK)的基本概念和使用方法。 - **Native开发方式与JAVA开发方式性能...

    Android笔记

    在Android开发领域,掌握基础是非常重要的,因为它构成了整个应用程序架构的核心。Android的组件是构建应用...同时,不断学习和跟进Android的新特性和最佳实践,可以使你的应用保持竞争力并满足用户日益增长的需求。

Global site tag (gtag.js) - Google Analytics