android学习日记——Intent与IntentFilter

来源:互联网 发布:tomcat 启动端口 编辑:程序博客网 时间:2024/05/30 05:06

回顾与总结:

  • Intent能启动Activity,Service,BroadcastReceiver三大系统组件
  • 指定Intent的Component属性就是显性定义Intent,只要为其赋予Component对象就行了。没有指定的即为隐性定义Intent,此时Intent所启动的组件能否启动取决于组件的<intent-filter>元素的配置:只要某个组件能满足的要求大于或等于Intent所指定的要求 ,那么该Intent就能启动
    //第一种方式显示声明IntentComponentName comp = new ComponentName(ThisClass.this,SecondClass.class);Intent intent = new Intent();intent.setComponent(intent);//第二种方式显示声明IntentIntent intent = new Intent(ThisClass.this,SecondClass.class);
  • 指定Intent的Component属性即是显性声明intent明确要启动哪个组件,被启动组件几乎无需配置<intent-filter>元素。此时,<intent-filter>中的Action,Category,Data,Type,Extra,Flag对于显性声明的Intent无效。
  • Action代表该Intent要完成的一个操作,而Category则是对Action 的补充说明类别信息。一个Intent只能携带一个Action,却能携带多个Category。但intent-filter能配置多个Action元素且至少有一个默认的Category,当某个Intent携带的Action属性被多个组件响应时,程序会弹出请求画面交给用户选择
  • Activity,service,receiver的子元素,能配置的要素有:0-N个action,0-N个category,0-1个data
  • 指定Action,Category调用系统Activity
  • Data,Type,Extra,Flag属性的设置
  • 使用Intent创建Tab页面
  • Intent一旦发出,Android都会准确找到相匹配的一个或多个Activity,Service或者BroadcastReceiver作响应。所以,不同类型的Intent消息不会出现重叠,即Broadcast的Intent消息只会发送给BroadcastReceiver,而决不会发送给Activity或者Service。由startActivity()传递的消息也只会发给Activity,由startService()传递的Intent只会发送给Service。
  • 注册的action的名字为.intent.action.YOUR_ACTION_NAME。(试验:如果不采用package-name,调用时会出现找不到Activity的异常)经测试,没有这个异常。
  • 在intent中传递的不是reference(指针),而是copy一份,我们修改对象,并不会影响已经copy进intent中bundle的数据,这点需要非常注意。
  • activity的intent-filter中可以有多个category描述,其中CATEGORY_DEFAULT表示可以使用implicit intent调用,当我们增加此项声明后,本应用就出现在匹配的activity列表中。同样,对于通过action name来调用的,不指定包名和类名的,也属于implicit intent,同样需要进行CATEGORY_DEFAULT的声明,否则会出现ActivityNotFoundException的错误。如果activity没有在intent fliter中设置为CATEGORY_DEFAULT,我们可以用PackageManager获取匹配的activities的信息,分析后得到确切的包名和类名,通过explicit的方式唤起该activity。
    此外Android说如果从launcher screen唤起时不需要DEFAULT,也就是此时acitivty只需MAIN和LAUNCHER,当然我们也可以DEFAULT设上。Android在DEFAULT上似乎有些繁杂,简单说如果我们不希望App被其他App通过implicit调用,我们就不要设置DEFAULT。

什么是Intent

 Intent直译“意图”,是对操作执行的抽象描述。主要解决Android应用的各项组件之间的通讯。Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。总的来说:Intent具有组件激活和数据携带的功能。

Intent的构成

Intetn对象的组成:Action,Data,Category,Extras,Flags,Component name

Action:说明要执行的操作,是字符串常量,更多Action可以到帮助文档Intent类找到。用户也可以自己定义自己的Action常量。通常使用setAction()和getAction()来设置

注意的点:一个Intent最多只能设置一个Action常量,启动的组件的Intent-filter能配置多个Action常量

常用的Action:

ACTION_CALL

activity

启动一个电话.

ACTION_EDIT

activity

显示用户编辑的数据.

ACTION_MAIN

activity

作为Task中第一个Activity启动

ACTION_SYNC

activity

同步手机与数据服务器上的数据.

ACTION_BATTERY_LOW

broadcast receiver

电池电量过低警告.

ACTION_HEADSET_PLUG

broadcast receiver

插拔耳机警告

ACTION_SCREEN_ON

broadcast receiver

屏幕变亮警告.

ACTION_TIMEZONE_CHANGED

broadcast receiver

改变时区警告.

Data:是执行动作的URI和MIME类型,不同的动作有不同的数据规格。即通常来为Action属性提供操作的数据。通俗的讲:Action是ACTION_EDIT时,数据域将是文档的URI;Action是ACTION_CALL时,数据域是 tel: URI ,带有要拨打的电话号码;如果Action是 ACTION_VIEW,则数据域是http: URI。匹配到Intent的组件知道Intent所携带的数据类型是很重要的。因为不可能叫一个文本编辑的组件去播放视频。

注意的点:

  • Data属性接受一个Uri对象,Uri对象用满足如下的字符串来表示:scheme://host:port/path 例如:content://com.android.contacts:8080/contacts/1
  • Type属性即MIME类型,指定该Data所指定的Uri对应的MIME类型,这种MIME类型可以是任何自定义的MIME类型,只要符合abc/xyz格式的字符串就行了
  • 数据类型也可以显式指定,比如setData()方法指定数据为URI,setType() 指定为MIME type,setDataAndType() 指定它既为URI又为MIME type。读取的时候URI用getData(),MIME type用getType()。但要注意如果分别设置Data属性,Type属性会相互覆盖。

MIME类型有2种形式:

1.1 单个记录的格式: vnd.android.cursor.item/vnd.yourcompanyname.contenttype,如:content://com.example.transportationprovider/trains/122(一条列车信息的uri)的MIME类型是vnd.android.cursor.item/vnd.example.rail

1.2 多个记录的格式:vnd.android.cursor.dir/vnd.yourcompanyname.contenttype,如:content://com.example.transportationprovider/trains (所有列车信息)的MIME类型是vnd.android.cursor.dir/vnd.example.rail

在AndroidManifest.xml为组件声明Data、Type属性时通过<data>元素来配置,但要注意的是Intent的Type属性要完全匹配对应组件在<Intent-filter>元素中的<data>元素的<mimeType>属性的设置,组件才能启动。但是Data属性的匹配却不同,不要求全部匹配。
  • 目标组件的<data>子元素只指定了android:scheme,android:host,android:port,android:path,那么Intent的Data属性的scheme,host,port,path要全部对应相同的属性值才可启动
  • 目标组件的<data>子元素只指定了android:scheme,android:host,android:path,那么只要Intent的Data属性的scheme,host,path对应相同的属性值就能启动了
  • 目标组件的<data>子元素只指定了android:scheme,android:host,android:port,那么只要Intent的Data属性的scheme,host,port对应相同的属性值就能启动了
  • 目标组件的<data>子元素只指定了android:scheme,android:host,那么只要Intent的Data属性的scheme,host,对应相同的属性值就能启动了
  • 目标组件的<data>子元素只指定了android:scheme,那么只要Intent的Data属性的scheme对应相同的属性值就能启动了
  • 另外注意的是如果没有指定android :host属性,那么android:port,android:path,是起不到作用的。总的来说:Intent携带的Data属性要大于或等于data元素配置的要求就行了。
Category:也是一个字符串常量,用于为Action 增加额外的附加类别信息,API文档中的Intent也定义了很多Category常量。与category相应的方法有添加addCategory()、移除removeCategory() 和获取所有category getCategories() 。
注意的点:
  • 一个Intent能携带多个Category,Intent-filter要配置至少一个Category属性(就算Intent没添加Category属性,也应该在intent-filter配置一个Intent.CATEGORY_DEFAULT属性)
Extras:传递给Intent的额外数据,以Bundle的形式定义,Bundle就像Map一样封装着一些键值对。通常用于在多个Action之间进行数据交换,Intent对象有一系列的putXXX()函数用于放入各种数据类型,相应的也有一系列的getXXX()函数用于读取数据。
  
Flags:各种类型的Flag。很多是用来指定Android系统如何启动activity,还有启动了activity后如何对待它。所有这些都定义在Intent类中。Intent可通过addFlags()来添加

component name:组件名称,即要处理这个Intent 的组件名称,由componentName封装。组件名称通过 setComponent(),setClass(),setClassName()设置,通过getComponent()获取。
  • 确定了component name,即显性定义了Intent,程序将不会根据Intent 的属性去寻找合适的组件。

Intent解析机制

Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有<intent-filter>及其中定义的Intent,通过PackageManager(注:PackageManager能够得到当前设备上所安装的
application package的信息)来查找能处理这个Intent的component。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:
1.1 如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;
1.2 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
1.3 如果Intent中的数据不是content:类型的URI,而且Intent也没有明确指定type,将根据Intent中数据的scheme(比如 http:或者mailto:)进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。
1.4 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。


参考:http://www.cnblogs.com/mengdd/archive/2013/03/18/2965839.html
http://www.cnblogs.com/feisky/archive/2010/01/16/1649081.html?t=1354802353061
http://blog.csdn.net/flowingflying/article/details/9270557
http://blog.csdn.net/flowingflying/article/details/9384389

0 0
原创粉丝点击