Android 学习 intent-filter、action、category标签使用

840 阅读13分钟

这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战

Intents and Intent Filters

我们知道,在android开发中,我们通过intent可以进行数据的传递。同时intent也是三大组件activity、service、broadcast的核心组件。具体看:

在activity中,一个Intent对象通过Context.startActivity()或者Activity.startActivityForResult()来加载一个activity或者让一个已经存在的activity做新事情,同时也可以通过Activity.setResult()为调用startActivityForResult()方法的activity返回信息。

在service中,一个Intent对象通过Context.startService()方法来启动一个service(服务),同样也可以通过Context.bindService()来建议通讯组件之间的绑定关系。

在broadCast中,一个Intent对象可以通过Context.sendBroadcast()方法、Context.sendOrderBroadcast()方法或Context.sendStickyBraodcast()方法发送广播。 下面我们来看看我们在intent-filter中配置的属性。

1、action:action属性定义了我们响应的动作

2、data属性,定义了不同类型的操作数据。不同的action对应的展示数据不同,例如,如果一个action的属性值为ACTION_EDIT,这个URI展示被编译的文本。如果action的属性为ACTION_CALL,那么data属性是tel:类型的URI。同样,如果action属性是ACTION_VIEW,则对应的是http:类型的URI。

image.png

3、Category,用于指定当前intent被处理的环境,一个intent-filter可以包含多个category属性。

image.png

简单介绍了四种属性,下面我们分别看看在android的各个组件之间的设置。

一、Activity属性配置

<activity android:allowTaskReparenting=["true" | "false"]
      android:alwaysRetainTaskState=["true" | "false"]
      android:clearTaskOnLaunch=["true" | "false"]
      android:configChanges=["mcc", "mnc", "locale",
                             "touchscreen", "keyboard", "keyboardHidden",
                             "navigation", "screenLayout", "fontScale", "uiMode",
                             "orientation", "screenSize", "smallestScreenSize"]
      android:enabled=["true" | "false"]
      android:excludeFromRecents=["true" | "false"]
      android:exported=["true" | "false"]
      android:finishOnTaskLaunch=["true" | "false"]
      android:hardwareAccelerated=["true" | "false"]
      android:icon="drawable resource"
      android:label="string resource"
      android:launchMode=["multiple" | "singleTop" |
                          "singleTask" | "singleInstance"]
      android:multiprocess=["true" | "false"]
      android:name="string"
      android:noHistory=["true" | "false"]  
      android:parentActivityName="string" 
      android:permission="string"
      android:process="string"
      android:screenOrientation=["unspecified" | "behind" |
                                 "landscape" | "portrait" |
                                 "reverseLandscape" | "reversePortrait" |
                                 "sensorLandscape" | "sensorPortrait" |
                                 "userLandscape" | "userPortrait" |
                                 "sensor" | "fullSensor" | "nosensor" |
                                 "user" | "fullUser" | "locked"]
      android:stateNotNeeded=["true" | "false"]
      android:taskAffinity="string"
      android:theme="resource or theme"
      android:uiOptions=["none" | "splitActionBarWhenNarrow"]
      android:windowSoftInputMode=["stateUnspecified",
                                   "stateUnchanged", "stateHidden",
                                   "stateAlwaysHidden", "stateVisible",
                                   "stateAlwaysVisible", "adjustUnspecified",
                                   "adjustResize", "adjustPan"] >   
. . .
</activity>

子节点:

  • 必须包含:< action >
  • 可以包含:< category>、< data>

看着是不是很多,很多我也没用过,下面就让我们分别来看看都是有什么用吧!

1. android:allowTaskReparenting

我们直接看一个官方的翻译吧! 这个属性用于设定Activity能够从启动它的任务中转移到另一个与启动它的任务有亲缘关系的任务中,转移时机是在这个有亲缘关系的任务被带到前台的时候。

  • 如果设置了true,则能够转移,如果设置了false,则这个Activity必须要保留在启动它的那个任务中。
  • 如果这个属性没有设置,那么其对应的元素的allowTaskReparenting属性值就会应用到这个Activity上。它的默认值是false。

通常,当Activity被启动时,它会跟启动它的任务关联,并它的整个生命周期都会保持在那个任务中。但是当Activity的当前任务不在显示时,可以使用这个属性来强制Activity转移到与当前任务有亲缘关系的任务中。这种情况的典型应用是把应用程序的Activity转移到与这个应用程序相关联的主任务中。

例如,如果一个电子邮件消息中包含了一个网页的链接,点击这个链接会启动一个显示这个网页的Activity。但是,由e-mail任务部分启动的这个Activity是由浏览器应用程序定义的。如果把它放到浏览器的任务中,那么在浏览器下次启动到前台时,这个网页会被显示,并且在e-mail任务再次显示时,这个Activity有会消失。

Activity的亲缘关系是由taskAffinity属性定义的。通过读取任务的根Activity的亲缘关系来判断任务的亲缘关系。因此,通过定义,任务中的根Activity与任务有着相同的亲缘关系。因此带有singleTask或singleInstance启动模式的Activity只能是任务的根节点,Activity的任务归属受限于standard和singleTop模式。

经典理解: 就是说,一个activity1原来属于task1,但是如果task2启动起来的话,activity1可能不再属于task1了,转而投奔task2去了。

当然前提条件是allowTaskReparenting,还有affinity设置 有点像,你捡到一条狗,在家里喂养几天觉得不错,当自己家的了;但是突然有一天他的主人找上门来了,小狗还是乖乖和主人走了。。。 用法 是否允许activity更换从属的任务,比如从短信息任务 切换到浏览器任务。

用来标记Activity能否从启动的Task移动到有着affinity的Task(当这个Task进入到前台时)——“true”,表示能移动,“false”,表示它必须呆在启动时呆在的那个Task里。

如果这个特性没有被设定,设定到元素上的allowTaskReparenting特性的值会应用到Activity上。默认值为“false”。

一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。典型用法是:把一个应用程序的Activity移到另一个应用程序的主Task中。

例如,如果e-mail中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为e-mail Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当e-mail Task再次进入前台时,就看不到它了。

Actvity的affinity是由taskAffinity特性定义的。Task的affinity是通过读取根Activity的affinity 决定。因此,根据定义,根Activity总是位于相同affinity的Task里。由于启动模式为“singleTask”和 “singleInstance”的Activity只能位于Task的底部,因此,重新宿主只能限于“standard”和“singleTop”模式。

2. android:alwaysRetainTaskState

这个属性用于设置Activity所属的任务状态是否始终由系统来维护。如果设置为true,则由系统来维护状态,设置为false,那么在某些情况下,系统会允许重设任务的初始状态。默认值是false。这个属性只对任务根节点的Activity有意义,其他所有的Activity都会被忽略。

通常,在某些情况中,当用户从主屏中重新启动一个任务时,系统会先清除任务(从堆栈中删除根节点Activity之上的所有Activity)。

但是,当这个属性被设置为true时,用户会始终返回到这个任务的最后状态,而不管中间经历了哪些操作。这样做是有好处的,例如,Web浏览器的应用就会保留很多用户不想丢失的状态,如多个被打开的标签页。

3. android:clearTaskOnLaunch

这个属性用来标记是否从task清除除根Activity之外的所有的Activity,“true”表示清除,“false”表示不清除,默认为“false”。同样,这个属性也只对根Activity起作用,其他的Activity都会被忽略。

如果设置了这个属性为“true”,每次用户重新启动这个应用时,都只会看到根Activity,task中的其他Activity都会被清除出栈。如果我们的应用中引用到了其他应用的Activity,这些Activity设置了allowTaskReparenting属性为“true”,则它们会被重新宿主到有共同affinity的task中。

4. android:configChanges

这个属性有很多属性值,当activity在运行的时候配置的属性发生变化,会执行onConfigurationChanged()方法。通俗一点说,我们给activity配置某个属性,如果某个属性变化,就走onConfigurationChanged()方法。

用途:当手机横放时, 程序的activity会重启, 以适应新的设备配置. 假如是一个编辑页面, 重启的结果会导致所写内容的丢失, 如果已经写了很多内容, 那将是一件极其蛋疼的事情。

如果不想横屏时activity自动重启, 可以在AndroidManifest文件的中声明android:configChanges属性, 当指定的系统配置发生改变的时候, 系统将不会重启activity, 而是执行程序中的public void onConfigurationChanged(Configuration newConfig)函数, 这样就可以让我们自己处理横屏这件事.

mcc:IMSI(国际移动用户识别码)发生改变,检测到SIM卡,或者更新MCC
mnc:IMSI网络发生改变,检测到SIM卡,或者更新MCC,其中mcc和mnc理论上不可能发生变化
locale:语言发生改变,用户选择了一个新的语言,文字应该重新显示
touchscreen:触摸屏发生改变,这通常是不应该发生的
keyboard:键盘类型发生改变,例如,用户使用了外部键盘
keyboardHidden:键盘发生改变,例如,用户使用了硬件键盘
navigation:导航发生改变,(这通常不应该发生) 举例:连接蓝牙键盘,连接后确实导致了navigation的类型发生变化。因为连接蓝牙键盘后,我可以使用方向键来navigate了
screenLayout:屏幕的布局发生改变,这可能导致激活不同的显示
fontScale:全局字体大小缩放发生改变
orientation:设备旋转,横向显示和竖向显示模式切换。
screenSize: 屏幕大小改变了
smallestScreenSize: 屏幕的物理大小改变了,如:连接到一个外部的屏幕上

5. android:enabled

该属性配置activity是否可用,true为可用,false为不可用。默认值为true。同样,该属性在标签中同样存在,application的属性值标志整个应用中是否可用,如果此activity是可用,则二者必须都为true。

6. android:excludeFromRecents

控制activity不在最近列表中显示,true为不显示,false为显示。

7. android:exported

改属性配置activity是否可以被别的应用程序的组件所使用,true是可以,false时只能被同一应用程序或具有相同userid的应用程序使用。 默认值取决于是否包含intent-filter属性。含有intent-filter默认为ture,否则为false。

8. android:finishOnTaskLaunch

该属性配置当任务重新启动时是否关闭已打开的activity。 参照使用

9. android:hardwareAccelerated

是否使用硬件加速器,主要用于绘制这方便。参照

10. android:icon

设置activity展现的图标,一般配合android:label属性使用,如果我们没设置,采用application标签配置的anddroid:icon属性。参照

11. android:label

设置activity展现的标签。如果未设置,同样采用application下的设置。

12. android:launchMode

设置activity的启动模式,这里也是我们上篇文章说的配置activity的启动模式,有四种类型。standard、singleTask、singleTop、singleInstance。默认值为standard。

13. android:multiprocess

设置activity是否在启动它的组件中的进程中。true为可以,false为不可以。一般情况下,应用中所有的activity运行在同一进程中,如果设置为true,这个activity可以运行在不同的进行中。

14. android:name

指定activity的名称,必填项。

15. android:noHistory

该属性设置当用户离开此activity(在屏幕上不可见)时是否将此activity移除任务栈(调用finish方法)。true代表finish,false代表不finish。默认值为false。 实例: 举例说明,假设有三个Activity分别是:A,B,C。这三个Activity可以依次顺序启动下一个Activity,比如,在A中做一个Button,用户点击后跳转到B ; 同样,在B中也做一个Button,点击跳转到C。C不再做Button,只是一个用以演示的空壳Activity。

在AndroidManifest.xml中配置B的属性为:android:noHistory=true

其他两个不做特别设置,仅仅作为一般的Activity处理。

可以观察到,A启动后,从A跳转到B,再从B跳转到C,进入C后,此时如果按返回键,将直接进入A,而不是B。简单的跳转逻辑路线:

A –> B –> C –> 按返回键 –> A

综上,可以这么理解android:noHistory=true对Activity行为的影响:当该Activity屏幕不可见时,相当于Android系统调用Activity的finish()方法结束了该Activity。

16. android:parentActivityName

设置activity的父类activity。这个activity在api16以上,为了在api4-16中使用,提供了 标签中的”android.support.PARENT_ACTIVITY”属性来设置。

<activity
android:name="com.example.app.ChildActivity"
android:label="@string/title_child_activity"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<!-- Parent activity meta-data to support API level 4+ -->
<meta-data
    android:name="android.support.PARENT_ACTIVITY"
    android:value="com.example.app.MainActivity" />
</activity>

17. android:permission

配置此activity所需的权限。如果通过 startActivity() 或 startActivityForResult()启动此activity,但是没有授予对应权限,则这个intent不会指定到这个activity。

18. android:process

配置了activity运行的进程名称。一般情况下是我们的默认包名,所有的activity运行在同一进程中。

19. android:screenOrientation

配置activity的展示设备的屏幕方向。

"unspecified"   默认值,系统选择方向。在具体情况下做出选择,不同的设备上不同。
"user"  用户当前喜好的方向。
"behind"    和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)
"landscape"  横屏
"portrait"  竖屏
"reverseLandscape"  横屏反向
"reversePortrait"   竖屏反向
"sensorLandscape"   横屏,正反取决于传感器
"sensorPortrait"    竖屏,正反取决于传感器
"sensor"    传感器决定
"fullSensor"    传感器决定,四个方向都可以,与sensor类似
"nosensor"      不使用传感器,方向由unspecified来决定

20. android:stateNotNeeded

配置activity关闭时是否保留它的状态。这个属性值默认为false。若设为true,则当activity重新启动时不会调用onSaveInstanceState()方法。同样onCreate()方法中的Bundle参数将会用null值传进去,也就是说,Activity每次启动都跟第一次启动一样。这样,在某种特殊场合下,由于用户按了Home键,该属性设置为true时,可以保证不用保存原先的状态引用,节省了空间资源,从而可以让Activity不会像默认设置那样Crash掉。

21. android:taskAffinity

Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系。我们知道,一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Task中度过自己的生命周期,这些Activity是从一而终的好榜样。参照实例1、参照实例2、参照实例3。

22. android:theme

设置activity的样式主题。如果activity没有设置,则使用application的样式主题,如果application样式主题没有设置,则使用系统默认主题。

23. android:uiOptions

用于activity的ui额外配置项。必须为以下两种值之一:”none”为默认项,没有UI项。”splitActionBarWhenNarrow”:ActionBar,在屏幕底部添加一个ActionBar选项。

24. android:windowSoftInputMode

activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性。 这个属性能影响两件事情: 【一】当有焦点产生时,软键盘是隐藏还是显示 【二】是否减少活动主窗口大小以便腾出空间放软键盘

【A】stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置
【B】stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示
【C】stateHidden:用户选择activity时,软键盘总是被隐藏
【D】stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的
【E】stateVisible:软键盘通常是可见的
【F】stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态
【G】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示
【H】adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间
【I】adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分

Service属性配置

<service android:enabled=["true" | "false"]
     android:exported=["true" | "false"]
     android:icon="drawable resource"
     android:isolatedProcess=["true" | "false"]
     android:label="string resource"
     android:name="string"
     android:permission="string"
     android:process="string" >
. . .
</service>

1. android:enabled

属性配置该service是否可用。true代表可用,false代表不可用。默认值为true。标签属性的android:enabled属性标志所有组件的可用性,所以必须为true。

2. android:exported

属性配置该service是否能被其它应用程序使用和交互。true为可以,false用于同一应用程序。